PyQt:管理两个MainWindow

时间:2015-04-15 14:19:25

标签: pyqt qmainwindow

我正在尝试使用PyQt为我的RFID访问控制项目管理两个MainWindow(MainWindow& AccessWindow)。 我想一直显示第一个MainWindow(Endless Loop)。 然后,当RFID阅读器(正在处理“自动阅读模式”)读取RFID标签时,我想隐藏它并显示第二个MainWindow。 所以在主python程序中我有一个伪“do while”循环(而True:和条件断开)来读取串口读取器提供的数据。然后我检查一下DB ..这不重要。所以触发事件是“当读者阅读某事时”。 我从另一个论坛得到了一些帮助,现在我有了这个:

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

#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("WELCOME", 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):
    def __init__(self):
        self.accueil = MainWindow(self)
        self.accueil.show()
        self.access = AccessWindow()

    def wait(self):
        # RFID READER ENDLESS LOOP
        while 1:

            global EPC_Code
            ser = serial.Serial(port='COM6', baudrate=115200)    
            a = ser.read(19).encode('hex')
            if (len(a)==38):
                EPC_Code = a[14:] 
                print ('EPC is : ' + EPC_Code)
                break
            else:
                continue
        ser.close()


        self.on_event(EPC_Code)

    def on_event(self, data):
        def refresh():
            self.toggle_widget(False)
            self.wait()
        # vérification des données 
        EPC_Code = data
        sql_command = "[Get_Access_RFID] @Code_RFID = '"+EPC_Code+"', @Code_Zone = '"+Code_Zone+"'"  #  STORED PROCEDURE
        db_cursor.execute(sql_command)
        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)

if __name__=='__main__':
    cnxn = """DRIVER={SQL Server};SERVER=***;PORT=***;UID=***;PWD=***;DATABASE=***"""
    db_connection = pyodbc.connect(cnxn)
    db_cursor = db_connection.cursor()
    print ('Connected TO DB & READY')
    app = QtGui.QApplication(sys.argv)
    main = Main()
    main.wait()
    sys.exit(app.exec_())

现在我的问题是,当我运行程序时,第一个窗口的文本没有出现,但是当我将我的徽章放在RFID阅读器附近时,会出现第二个窗口的文本。

1 个答案:

答案 0 :(得分:0)

而不是两个MainWindow,创建一个。作为内容,创建两个扩展QtGui.QWidget MainViewAccessView的类。而不是替换窗口,只需将正确的视图放入窗口。这样,您可以在不打开/关闭窗口的情况下交换视图。

如果使用布局,则窗口将调整大小以适合视图。

下一个问题是你阻止了UI线程,这意味着Qt无法处理事件(比如" paint UI" event)。要解决此问题,您必须在后台线程中移动RFID处理代码。您可以从此后台线程发出信号以更新UI。

注意:您不能从线程调用UI代码!!只是发出信号。 PyQt的主循环将看到它们并处理它们。

相关: