管理两个主窗口MainWindow和线程

时间:2015-04-16 13:30:52

标签: python pyqt4

我更新了一些事情,比如从线程类中调用on_event方法,现在我有了这段代码:

# -*- coding: utf-8 -*-
from PyQt4 import QtCore, QtGui
import sys, pyodbc, serial
import os
import time
import thread
from PyQt4.QtCore import pyqtSignal
from PyQt4.QtCore import QObject, pyqtSignal

#Variables
Code_Zone = "d"

class MainWindow(QtGui.QWidget):
    def __init__(self, main):
        super(MainWindow, self).__init__()
        self.main = main
        self.grid = QtGui.QGridLayout(self)
        self.welcome = QtGui.QLabel("Bienvenue sur www.developpez.net", self)
        self.grid.addWidget(self.welcome, 2, 2, 1, 5)

class AccessWindow(QtGui.QWidget):
    def __init__(self):
        super(AccessWindow, self).__init__()
        self.setMinimumSize(150, 50)
        self.grid = QtGui.QGridLayout(self)
        self.label = QtGui.QLabel(self)
        self.grid.addWidget(self.label, 1, 1, 1, 1)

class Main(object):
    global EPC_Code
    def __init__(self):
        self.accueil = MainWindow(self)
        self.accueil.show()
        self.access = AccessWindow()

    def on_event(self, data):
        def refresh():
            self.toggle_widget(False)
            #c = AThread()
            c.run()
            #self.wait()
        # vérification des données 
        EPC_Code = data
        cnxn = """DRIVER={SQL Server};SERVER=Aziz-PC\SQLEXPRESS;PORT=1433;UID=poleindus;PWD=poleindus;DATABASE=indusdb"""
        db_connection = pyodbc.connect(cnxn)
        db_cursor = db_connection.cursor()
        print ('Connected TO DB & READY')
        sql_command = "EXECUTE [Get_Access_RFID] @Code_RFID = '"+EPC_Code+"', @Code_Zone = '"+Code_Zone+"'"
        db_cursor.execute("EXECUTE [Get_Access_RFID] @Code_RFID = '"+EPC_Code+"', @Code_Zone = '"+Code_Zone+"'")
        rows = db_cursor.fetchone()
        result= str(rows[0])
        print ("result = " + str(result))
        if result == "True":
            # si OK
            self.access.label.setText('ACCESS GRANTED')
        else:
            # si pas OK
            self.access.label.setText('ACCESS DENIED')
        self.toggle_widget(True)
        QtCore.QTimer.singleShot(2000, refresh)

    def toggle_widget(self, b):
        self.accueil.setVisible(not b)
        self.access.setVisible(b)


class AThread(QtCore.QThread):
    rfid_event = pyqtSignal(str, name='rfid_event')

    def run(self):
        while 1:
            ser = serial.Serial(port='COM6', baudrate=115200)
            a = ser.read(19).encode('hex')
            ser.close()

            if len(a) == 38:
                EPC_Code = a[14:]
                print ('EPC is : ' + EPC_Code)
                self.rfid_event.emit(EPC_Code)

if __name__=='__main__':
    #cnxn = """DRIVER={SQL Server};SERVER=Aziz-PC\SQLEXPRESS;PORT=1433;UID=poleindus;PWD=poleindus;DATABASE=indusdb"""
    #db_connection = pyodbc.connect(cnxn)
    #db_cursor = db_connection.cursor()
    #print ('Connected TO DB & READY')
    app = QtGui.QApplication(sys.argv)
    main = Main()
    thread = AThread()
    thread.rfid_event.connect(Main().on_event)
    thread.start()
    #main = Main()
    sys.exit(app.exec_())

我已经在代码的顶部添加了这一行,现在,我有另一个错误:执行的第一个参数必须是字符串或unicode查询。当我检查sql命令的值时,我发现它等于to:PyQt4.QtCore.QString(u" EXECUTE [Get_Access_RFID] @Code_RFID =' e20010712904019411709bdd',@ Code_Zone =' d'")

1 个答案:

答案 0 :(得分:0)

您在Main中创建了新的AThread。这意味着你现在有两个(更糟糕的是,每次处理RFID事件时都会创建一个)。

此外,您不允许从线程内部调用来自Main的方法。想象一下,如果线程在第一次调用返回之前再次调用它们会发生什么:数据将被破坏。

相反,您必须在AThread中声明信号并致电emit()发送信号。然后,最后一段代码中的Main可以连接到此信号。

class AThread(QtCore.QThread):
    rfid_event = pyqtSignal(str, name='rfid_event')

    def run(self):
        while 1:
            ser = serial.Serial(port='COM6', baudrate=115200)
            a = ser.read(19).encode('hex')
            ser.close()

            if len(a) == 38:
                EPC_Code = a[14:]
                print ('EPC is : ' + EPC_Code)
                self.rfid_event.emit(EPC_Code)

以及后来的__main__代码:

main = Main()
thread = AThread()
thread.rfid_event.coonect(Main.on_event)
thread.start()
#main = Main()
sys.exit(app.exec_())

另请注意thread.finished.connect(app.exit)无法正常工作:该主题包含无限循环且永不完成。相反,您应该在主窗口关闭时终止线程。

我还修复了对串口的访问;你必须每次关闭它。

相关问题