2016-04-14 84 views
0

我试着从我的数据库获取一行,显示在TK文本组件如果为1,并从显示中删除,如果0显示SQLite的输出

我到目前为止的代码显示了一行一卡。当我第二次扫描时,我得到一个错误。

SQLite objects created in a thread can be used in that same thread.The object was created in thread id 6740 and this is thread id 6320 
<traceback object at 0x02AAC418> 
<class 'sqlite3.ProgrammingError'> 
Traceback (most recent call last): 
    File "C:\rfid\main2.py", line 66, in <module> 
    cardmonitor.addObserver(cardobserver) 
    File "C:\Python27\lib\site-packages\smartcard\CardMonitoring.py", line 105, in addObserver 
    observer.update(self, (self.rmthread.cards, [])) 
    File "C:\rfid\main2.py", line 56, in update 
    a(tag) 
    File "C:\rfid\main2.py", line 25, in a 
    root.mainloop() 
    File "C:\Python27\lib\lib-tk\Tkinter.py", line 1017, in mainloop 
    self.tk.mainloop(n) 
KeyboardInterrupt 

下面

import sqlite3 as db 
import os 
from prettytable import from_db_cursor 
from smartcard.scard import * 
from smartcard.util import toHexString 
from prettytable import from_db_cursor 
from smartcard.CardMonitoring import CardMonitor, CardObserver 
import time 
from Tkinter import Tk, BOTH, INSERT, Text 

def main(tag): 

     q = "SELECT * FROM CARDS WHERE TAG=?" 
     up = "UPDATE CARDS SET FLAG = (CASE WHEN FLAG=0 THEN 1 ELSE 0 END) WHERE TAG=?" 
     id = "SELECT * FROM CARDS WHERE TAG=?" 
     cursor.execute(q, (tag,)) 
     cursor.execute(up, (tag,)) 
     conn.commit() 
     for row in cursor.execute(id, (tag,)): 
     print row [1] + row[2] #debugging to console 
     r1 = str(row[1]) 
     r2 = str(row[2]) 
     msg = str(r1 + r2) 
     text_widget = Text(root, font='times 40 bold', bg='Green') 
     text_widget.pack(fill=BOTH, expand=0) 
     text_widget.tag_configure('tag-center', wrap='word', justify='center') 
     text_widget.insert(INSERT, msg, 'tag-center') 
     root.mainloop() 
class printobserver(CardObserver): 
    def update(self, observable, (addedcards, removedcards)): 
     previousIdString = "" 
     idString = "" 
     for card in addedcards: 
     if addedcards: 
      hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) 
      assert hresult==SCARD_S_SUCCESS 
      hresult, readers = SCardListReaders(hcontext, []) 
      assert len(readers)>0 
      reader = readers[0] 
      hresult, hcard, dwActiveProtocol = SCardConnect(
      hcontext, 
      reader, 
      SCARD_SHARE_SHARED, 
      SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) 
      hresult, response = SCardTransmit(hcard,dwActiveProtocol,[0xFF,0xCA,0x00,0x00,0x04]) 
      v = toHexString(response, format=0) 
      tag = str(v) 
      main(tag) 
conn = db.connect('cards3.db') 
root = Tk() 
while True: 
cursor = conn.cursor() 
cardmonitor = CardMonitor() 
cardobserver = printobserver() 
cardmonitor.addObserver(cardobserver) 
cardmonitor.deleteObserver(cardobserver) 
time.sleep(2) 

更新主要代码: 从下面我的答案现在已经厌倦了下面。

将conn.cursor移入类中,但是相同。不同的错误是Coursor is not defined

import sqlite3 as db 
import os 
from prettytable import from_db_cursor 
from smartcard.scard import * 
from smartcard.util import toHexString 
from prettytable import from_db_cursor 
from smartcard.CardMonitoring import CardMonitor, CardObserver 
import time 
from Tkinter import Tk, BOTH, INSERT, Text 

def main(tag): 

     q = "SELECT * FROM CARDS WHERE TAG=?" 
     up = "UPDATE CARDS SET FLAG = (CASE WHEN FLAG=0 THEN 1 ELSE 0 END) WHERE TAG=?" 
     id = "SELECT * FROM CARDS WHERE TAG=?" 
     cursor.execute(q, (tag,)) 
     cursor.execute(up, (tag,)) 
     conn.commit() 
     for row in cursor.execute(id, (tag,)): 
     print row [1] + " has been checked " + ('in' if row[2] else 'out') 
     r1 = str(row[1]) 
     r2 = str(row[2]) 
     mseg = str(r1 + r2) 
     text_widget = Text(root, font='times 40 bold', bg='Green') 
     text_widget.pack(fill=BOTH, expand=0) 
     text_widget.tag_configure('tag-center', wrap='word', justify='center') 
     text_widget.insert(INSERT, r1 + r2, 'tag-center') 
     root.mainloop() 

class printobserver(CardObserver): 
    cursor = conn.cursor() 
    def update(self, observable, (addedcards, removedcards)): 
     previousIdString = "" 
     idString = "" 
     for card in addedcards: 
     if addedcards: 
      hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) 
      assert hresult==SCARD_S_SUCCESS 
      hresult, readers = SCardListReaders(hcontext, []) 
      assert len(readers)>0 
      reader = readers[0] 
      hresult, hcard, dwActiveProtocol = SCardConnect(
      hcontext, 
      reader, 
      SCARD_SHARE_SHARED, 
      SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) 
      hresult, response = SCardTransmit(hcard,dwActiveProtocol,[0xFF,0xCA,0x00,0x00,0x04]) 
      v = toHexString(response, format=0) 
      tag = str(v) 
      main(tag) 

conn = db.connect('cards3.db') 
root = Tk() 
while True: 

cardmonitor = CardMonitor() 
cardobserver = printobserver() 
cardmonitor.addObserver(cardobserver) 
cardmonitor.deleteObserver(cardobserver) 
time.sleep(2) 

也有疲惫的投入主要和更新,但还是同样的错误

def main(tag): 
     cursor = conn.cursor 
     q = "SELECT * FROM CARDS WHERE TAG=?" 
     up = "UPDATE CARDS SET FLAG = (CASE WHEN FLAG=0 THEN 1 ELSE 0 END) WHERE TAG=?" 
     id = "SELECT * FROM CARDS WHERE TAG=?" 
     cursor.execute(q, (tag,)) 
     cursor.execute(up, (tag,)) 
     conn.commit() 
     for row in cursor.execute(id, (tag,)): 
     print row [1] + " has been checked " + ('in' if row[2] else 'out') 
     r1 = str(row[1]) 
     r2 = str(row[2]) 
     mseg = str(r1 + r2) 
     text_widget = Text(root, font='times 40 bold', bg='Green') 
     text_widget.pack(fill=BOTH, expand=0) 
     text_widget.tag_configure('tag-center', wrap='word', justify='center') 
     text_widget.insert(INSERT, r1 + r2, 'tag-center') 
     root.mainloop() 

def update(self, observable, (addedcards, removedcards)): 
      previousIdString = "" 
      idString = "" 
      for card in addedcards: 
      if addedcards: 
       hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) 
       assert hresult==SCARD_S_SUCCESS 
       hresult, readers = SCardListReaders(hcontext, []) 
       assert len(readers)>0 
       reader = readers[0] 
       hresult, hcard, dwActiveProtocol = SCardConnect(
       hcontext, 
       reader, 
       SCARD_SHARE_SHARED, 
       SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) 
       hresult, response = SCardTransmit(hcard,dwActiveProtocol,[0xFF,0xCA,0x00,0x00,0x04]) 
       v = toHexString(response, format=0) 
       tag = str(v) 
       main(tag) 
       cursor = conn.cursor 

如果我删除所有的传统知识的东西,并把cursor = conn.cursor以上while True:我可以让扫描卡没有问题

def main(tag): 
      cursor = conn.cursor 
      q = "SELECT * FROM CARDS WHERE TAG=?" 
      up = "UPDATE CARDS SET FLAG = (CASE WHEN FLAG=0 THEN 1 ELSE 0 END) WHERE TAG=?" 
      id = "SELECT * FROM CARDS WHERE TAG=?" 
      cursor.execute(q, (tag,)) 
      cursor.execute(up, (tag,)) 
      conn.commit() 
      for row in cursor.execute(id, (tag,)): 
      print row [1] + " has been checked " + ('in' if row[2] else 'out') 
+0

'在一个线程中创建的SQLite对象可以在同一个线程中使用.'抓取输出不可变! – dsgdfg

+0

就像把它放到一个txt文件然后读入它? – shaggs

+0

你好像多次调用'mainloop'。为什么每次调用'main'时都会调用它?它只需要在程序的整个生命周期中调用一次。这可能不是这个具体问题的原因,但这绝对是一个问题。 –

回答

0

SQLite objects created in a thread can be used in that same thread.The object was created in thread id 6740 and this is thread id 6320

class printobserver(CardObserver)必须创建一个新线程,sqlite3不支持太多的并发。但是,它跨越不同的流程。从您的代码注意这个剪断:

printobserver

main(tag) 

主要

q = "SELECT * FROM CARDS WHERE TAG=?" 
     up = "UPDATE CARDS SET FLAG = (CASE WHEN FLAG=0 THEN 1 ELSE 0 END) WHERE TAG=?" 
     id = "SELECT * FROM CARDS WHERE TAG=?" 
     cursor.execute(q, (tag,)) 
     cursor.execute(up, (tag,)) 
     conn.commit() 

全局命名空间while-loop

cardobserver = printobserver() 
cardmonitor.addObserver(cardobserver) 
cardmonitor.deleteObserver(cardobserver) 

由于您从printobserver对象(显然此对象每次创建一个新线程)呼叫main(),因此您在全局命名空间的主线程中生成了cursor,并且您正在调用main()中的游标,该游标现在从新的线程,你得到这个错误。

既然你不使用cursor从外部main(),我建议连接到数据库中的main()顶部,初始化cursor,然后做任何你需要做的,并在主要的底部从数据库断开连接。或者,您可以在printobserver对象内执行此操作,因为游标初始化仍将与main()位于同一线程中。