【问题标题】:Display SQLite output in TK python在 TK python 中显示 SQLite 输出
【发布时间】:2016-04-14 12:06:13
【问题描述】:

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

也厌倦了放入 main 和 update 但仍然是同样的错误

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

如果我删除所有 TK 内容并将 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')

【问题讨论】:

  • SQLite objects created in a thread can be used in that same thread. 抓取输出不可变!
  • 就像把它放到一个txt文件然后读进去?
  • 您似乎多次致电mainloop。为什么每次调用main 时都调用它?它需要在程序的整个生命周期中只调用一次。这可能不是这个特定问题的原因,但它绝对是一个问题。
  • 另外,你为什么要生成一个新的sqlite3.conn.cursor() inside while-loop?
  • Mainloop() 被要求调用一次。我意识到我把它放在了错误的地方,所以把它修好了,但忘了把旧的拿掉。至于conn.cursor,把它放在那里看看它是否会在while loop之外出现错误时工作。

标签: python python-2.7 tkinter sqlite


【解决方案1】:

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 不支持太多并发。但是,它跨越不同的进程。请注意您的代码中的此片段:

打印观察者

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,并且您在@ 中调用游标现在从新线程执行的 987654331@,您会收到此错误。

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

【讨论】:

    猜你喜欢
    • 2019-07-28
    • 2013-11-27
    • 1970-01-01
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多