0

i'm trying to manage two MainWindow (MainWindow & AccessWindow) with PyQt for my RFID ACCESS CONTROL Project. I want to show the first MainWindow all time (Endless Loop). Then, i want to hide it and show the second MainWindow when the RFID Reader (who's working on "auto-reading mode") read an RFID Tag. so in the main python program i have a pseudo "do while" loop (while True: and break with a condition) to read on serial port the data provided by the reader. Then i check a DB.. It's not important. So the trigger event is "when the reader read something). I got some help from another forum and now i have this:

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

and now my problem is that the text of the first window doesn't appear when i run the program but the text of the second window appear when i keep my badge near the RFID Reader.

1 Answers1

2

Instead of two MainWindow, create one. As content, create two classes which extend QtGui.QWidget called MainView and AccessView. Instead of replacing the window, just put the correct view into the window. That way, you can swap views without opening/closing windows.

If you use a layout, then the window will resize to fit the view.

The next problem is that you block the UI thread which means Qt can't handle events (like the "paint UI" event). To fix this, you must move the RFID handling code in a background thread. You can emit signals from this background thread to update the UI.

Note: You must not call UI code from a thread!! Just emit signals. PyQt's main loop will see them and process them.

Related:

Community
  • 1
  • 1
Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820