PyQt:管理两个MainWindow

PyQt : Manage two MainWindow

我正在尝试使用 PyQt 为我的 RFID 访问控制项目管理两个 MainWindow(MainWindow 和 AccessWindow)。 我想一直显示第一个主窗口(无限循环)。 然后,我想隐藏它并在 RFID Reader(正在处理 "auto-reading mode")读取 RFID 标签时显示第二个 MainWindow。 所以在主 python 程序中,我有一个伪 "do while" 循环(当 True:并中断条件时)在串行端口上读取 reader 提供的数据。然后我检查一个数据库..这并不重要。所以触发事件是“当 reader 读到一些东西时)。 我从另一个论坛得到了一些帮助,现在我得到了这个:

# -*- 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_())

现在我的问题是当我 运行 程序时第一个 window 的文本没有出现,但是当我保留我的程序时第二个 window 的文本出现RFID 附近的徽章 Reader.

创建一个,而不是两个 MainWindow。作为内容,创建两个扩展 QtGui.QWidget 的 类,称为 MainViewAccessView。不要替换 window,只需将正确的视图放入 window。这样,您可以在没有 opening/closing windows.

的情况下交换视图

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

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

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

相关: