如何运行 nfcpy card reader system on wxPython GUI application

how to run nfcpy card reader system on wxPython GUI application

我是 wxPython GUI 应用程序的新手

我想创建我的 python 脚本作为 GUI 应用程序

This is my sample script

import binascii
import nfc

class MyCardReader(object):

   def on_connect(self, tag):
      print "touched"
      self.idm = binascii.hexlify(tag.idm)
      return True

   def read_id(self):
      clf = nfc.ContactlessFrontend('usb')
      try:
         clf.connect(rdwr={'on-connect': self.on_connect})
      finally:
         clf.close()

if __name__ == '__main__':
  cr = MyCardReader()
  while True:
    print "touch card:"
    cr.read_id()
    print "released"
    print cr.idm

how to run the above script as GUI app using wxPython, i was already try but it doesnt work, what is wrong in my code.

#-*- encoding: utf-8 -*-
import wx
import nfc
import binascii
class MyFrame(wx.Frame):

   def __init__(self, parent, title):
      wx.Frame.__init__(self, parent, title=title, size=(400, 500))
      panel = wx.Panel(self)
      self.Show(True)
      while True:
        clf = nfc.ContactlessFrontend('usb')
        clf.connect(rdwr={'on-connect': self.on_connect})
        self.text = wx.StaticText(panel, label='i want to print the return value here', pos=(100, 100))

  def on_connect(self, tag):
      self.idm = binascii.hexlify(tag.idm)
      return self.idm

app = wx.App(False)
frame = MyFrame(None, 'card reader app')
app.MainLoop()

您已将您的代码投入无限的 While True 循环,这意味着 Gui 主循环永远不会到达 运行。
您应该根据来自卡片 reader 的输入添加一个 event,或者为了让您开始,只需添加一个按钮并在按下按钮时访问 reader。这会让您快速起床 运行。
这是您的代码,经过调整后可以在我的电脑上运行,只是为了证明它可以正常工作。
注意 self.text.SetLabel()

的使用
import wx
#import nfc
import binascii
class MyFrame(wx.Frame):

    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=(400, 500))
        panel = wx.Panel(self)
        self.text = wx.StaticText(panel, label='i want to print the return value here', pos=(100, 100))
        self.read = wx.Button(panel, -1, label="Read Card", pos=(100, 200))
        self.read.Bind(wx.EVT_BUTTON, self.on_button)
        self.Show()
        self.n = 0

    def on_button(self,event):
#        clf = nfc.ContactlessFrontend('usb')
#        clf.connect(rdwr={'on-connect': self.on_connect})
        self.n+=1
        self.on_connect("abc")
        self.text.SetLabel("Card Value "+self.idm+" "+str(self.n))

    def on_connect(self, tag):
        self.idm = binascii.hexlify(tag)#.idm)
        return self.idm

app = wx.App()
frame = MyFrame(None, 'card reader app')
app.MainLoop()

nfc.ContactlessFrontend.connect() 方法在调用者线程上下文中运行,因此在至少连接一个标签之前不会返回(如果 'on-connect' 回调 returns True 它将进一步等待直到标签消失)。 wx.App.mainLoop() 也在调用者线程上下文中 运行 分派 window 事件。因此,正确的方法是 运行 在单独的线程中发现标签并将事件发送到渲染帧。下面是一个示例,当标签靠近 reader.

时显示标签标识符
#!/usr/bin/env python
import wx
import wx.lib.newevent
import nfc
import threading
from binascii import hexlify

ShowCardEvent, SHOW_CARD_EVENT = wx.lib.newevent.NewEvent()
GoneCardEvent, GONE_CARD_EVENT = wx.lib.newevent.NewEvent()


class TagReader(threading.Thread):
    def __init__(self, wx_frame):
        super(TagReader, self).__init__(name="TagReader")
        self.terminate = False
        self.wx_frame = wx_frame

    def run(self):
        clf = nfc.ContactlessFrontend('usb')
        rdwr_options = {
            'on-connect': self.on_tag_connect,
            'on-release': self.on_tag_release
        }
        while not self.terminate:
            clf.connect(rdwr=rdwr_options, terminate=lambda: self.terminate)

    def on_tag_connect(self, tag):
        wx.PostEvent(self.wx_frame, ShowCardEvent(tag=tag))
        return True

    def on_tag_release(self, tag):
        wx.PostEvent(self.wx_frame, GoneCardEvent())


class Frame(wx.Frame):
    def __init__(self, title):
        super(Frame, self).__init__(None, title=title, size=(500, 200))
        self.text = wx.StaticText(wx.Panel(self), pos=(100, 100))
        self.Bind(SHOW_CARD_EVENT, self.show_card_event)
        self.Bind(GONE_CARD_EVENT, self.gone_card_event)
        self.Bind(wx.EVT_CLOSE, self.close_window_event)
        wx.PostEvent(self, GoneCardEvent())
        self.Show()

    def close_window_event(self, event):
        self.Destroy()

    def show_card_event(self, event):
        self.text.SetLabel("Card ID {}".format(hexlify(event.tag.identifier)))

    def gone_card_event(self, event):
        self.text.SetLabel("no card")


app = wx.App()
reader = TagReader(Frame('card reader app'))
reader.start()
app.MainLoop()
reader.terminate = True  # tell the reader to terminate
reader.join()  # and wait for the reader thread to finish