在TK python中显示SQLite输出

时间:2016-04-14 12:06:13

标签: python python-2.7 tkinter sqlite

我试图从我的数据库中获取一行以显示在tk文本小部件上(如果为1)并从显示中移除(如果为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
<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')

1 个答案:

答案 0 :(得分: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 )

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

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