Search code examples
pythonmultithreadingpyqtpyqt4rfid

PyQt4 setText dynamic from other class with a link script


Everything works instead of this inconvenience. I tried to set text, but it doesn't work. Every new scan it should appear new text scanned from tag, but it is the same text from global variables from RFID script.

from PyQt4 import QtCore, QtGui
from ui_mainwindow import Ui_MainWindow
import threading
import RPi.GPIO as GPIO
import MFRC522
import signal
import time

class MainWindow(QtGui.QMainWindow):
    state1, state2, state3, state4 = range(4)
    stateChanged = QtCore.pyqtSignal(int)


    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.stateChanged.connect(self.onChangeState)
        threading.Thread(target=self.reading, daemon=True).start()

    def onChangeState(self, state):
        MIFAREReader = MFRC522.MFRC522()
        if state == MainWindow.state1:

            self.ui.label_4.setText(MIFAREReader.tagId) ###-->text from RFID script
            self.ui.label_2.setText(MIFAREReader.tagName) ###-->text from RFID script
            self.ui.label_3.setText(MIFAREReader.tagDetails) ###-->text from RFID script

            self.ui.label_3.show()
            self.ui.label_2.show()
            self.ui.label_4.show()
            self.ui.groupBox.setStyleSheet("background: white;\n"
                    "border-style: solid;\n"
                    "border-width: 1px;\n"
                    "border-radius: 20px;")

        elif state == MainWindow.state2:
            self.ui.label_3.hide()
            self.ui.label_2.hide()
            self.ui.label_4.hide()
            self.ui.groupBox.setStyleSheet("background: white url(scan.png) no-repeat center;\n"
                    "border-style: solid;\n"
                    "border-width: 1px;\n"
                    "border-radius: 20px;")

        elif state == MainWindow.state3:
            self.ui.groupBox.setStyleSheet("background: white url(accsd.png) no-repeat center;\n"
                    "border-style: solid;\n"
                    "border-width: 1px;\n"
                    "border-radius: 20px;")

        elif state == MainWindow.state4:
            self.ui.groupBox.setStyleSheet("background: white url(scan.png) no-repeat center;\n"
                    "border-style: solid;\n"
                    "border-width: 1px;\n"
                    "border-radius: 20px;")


    def reading(self):
        ### Event Functions ###
        continue_reading = True
        # Hook the SIGINT
        #signal.signal(signal.SIGINT, end_read)
        # Create an object of the class MFRC522
        MIFAREReader = MFRC522.MFRC522()
        # This loop keeps checking for chips. If one is near it will get the UID and authenticate
        while continue_reading:
            # Scan for cards    
            (status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)
            # Get the UID of the card
            (status,uid) = MIFAREReader.MFRC522_Anticoll()

            # If we have the UID, continue
            if status == MIFAREReader.MI_OK:
                # This is the default key for authentication
                key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
                # Select the scanned tag
                MIFAREReader.MFRC522_SelectTag(uid)
                # Authenticate
                status = MIFAREReader.MFRC522_Auth(MIFAREReader.PICC_AUTHENT1A, 8, key, uid)
                # Check if authenticated
                if status == MIFAREReader.MI_OK:

                    MIFAREReader.MFRC522_Read(8)
                    self.stateChanged.emit(MainWindow.state1)
                    time.sleep(3)
                    MIFAREReader.MFRC522_StopCrypto1()
                    self.stateChanged.emit(MainWindow.state2)

                else:
                    self.stateChanged.emit(MainWindow.state3)
                    time.sleep(2)
                    self.stateChanged.emit(MainWindow.state4)


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

This is the code for text I want to be printed in the GUI from script of the RFID.

class MFRC522(): 
  #Strings for GUI
  tagId = "txt"
  tagName = "txt"
  tagDetails = "txt"
      #########
      #########
      #########
      #########
  def MFRC522_Read(self, blockAddr):
    self.tagId = "Product ID: "
    self.tagName = "Product Name: "
    self.tagDetails = "Product Details: "

    recvData = []
    recvData.append(self.PICC_READ)
    recvData.append(blockAddr)
    pOut = self.CalulateCRC(recvData)
    recvData.append(pOut[0])
    recvData.append(pOut[1])
    (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, recvData)
    if not(status == self.MI_OK):
      message = "Error while reading!"
##      print (message)
    i = 0

    backDataText = ""
    if len(backData) == 16:
        for x in range(0, len(backData)):
            backDataText = backDataText + chr(int(backData[x]))

    for iA in range(len(self.indexMark)):
        numbersFound = re.search(r'\d+', backDataText)
        DataTextNumeric = numbersFound.group()
        DataTextNumeric = int(DataTextNumeric)
        if DataTextNumeric == self.indexMark[iA]:
            message = "Product Code: %s \n Product Name: %s \n Details: %s" % (backDataText, self.productsName[iA], self.productsDetails[iA])
            Id = DataTextNumeric
            Name = self.productsName[iA]
            Details = self.productsDetails[iA]
##            print (message)

            break
    self.tagId += str(Id)
    self.tagName += Name
    self.tagDetails += Details
    print (self.tagId) ###-->"Product ID: ####" this prints in the console   
                          every time I scan a new thing, so the code works

The code is good, but it's something that I cannot understand how it's working. Everytime I read a new tag, the message on GUI is the value of global variables from RFID script not changed. I do not have so much experience, I am sorry for that.


Solution

  • With the following line in onChangeState():

    MIFAREReader = MFRC522.MFRC522()
    

    you are creating another object, which is different from the object created in reading(), and consequently that will not have the RFID information, that leads me to think that you have to reinforce your OOP concepts.

    As indicated in your previous question, the data should be sent using the signals:

    from PyQt4 import QtCore, QtGui
    from ui_mainwindow import Ui_MainWindow
    import threading
    import RPi.GPIO as GPIO
    import MFRC522
    import signal
    import time
    
    class MainWindow(QtGui.QMainWindow):
        state1, state2, state3, state4 = range(4)
        stateChanged = QtCore.pyqtSignal(int)
        infoChanged = QtCore.pyqtSignal(str, str, str)
    
        def __init__(self, parent=None):
            QtGui.QMainWindow.__init__(self, parent)
            self.ui = Ui_MainWindow()
            self.ui.setupUi(self)
            self.infoChanged.connect(self.onInfoChanged)
            self.stateChanged.connect(self.onChangeState)
            threading.Thread(target=self.reading, daemon=True).start()
    
        def onInfoChanged(self, text1, text2, text3):
            self.ui.label_4.setText(text1) ###-->text from RFID script
            self.ui.label_2.setText(text2) ###-->text from RFID script
            self.ui.label_3.setText(text3) ###-->text from RFID script
    
        def onChangeState(self, state):
            if state == MainWindow.state1:
                self.ui.label_3.show()
                self.ui.label_2.show()
                self.ui.label_4.show()
                self.ui.groupBox.setStyleSheet("background: white;\n"
                        "border-style: solid;\n"
                        "border-width: 1px;\n"
                        "border-radius: 20px;")
    
            elif state == MainWindow.state2:
                self.ui.label_3.hide()
                self.ui.label_2.hide()
                self.ui.label_4.hide()
                self.ui.groupBox.setStyleSheet("background: white url(scan.png) no-repeat center;\n"
                        "border-style: solid;\n"
                        "border-width: 1px;\n"
                        "border-radius: 20px;")
    
            elif state == MainWindow.state3:
                self.ui.groupBox.setStyleSheet("background: white url(accsd.png) no-repeat center;\n"
                        "border-style: solid;\n"
                        "border-width: 1px;\n"
                        "border-radius: 20px;")
    
            elif state == MainWindow.state4:
                self.ui.groupBox.setStyleSheet("background: white url(scan.png) no-repeat center;\n"
                        "border-style: solid;\n"
                        "border-width: 1px;\n"
                        "border-radius: 20px;")
    
    
        def reading(self):
            ### Event Functions ###
            continue_reading = True
            # Hook the SIGINT
            #signal.signal(signal.SIGINT, end_read)
            # Create an object of the class MFRC522
            MIFAREReader = MFRC522.MFRC522()
            # This loop keeps checking for chips. If one is near it will get the UID and authenticate
            while continue_reading:
                # Scan for cards    
                (status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)
                # Get the UID of the card
                (status,uid) = MIFAREReader.MFRC522_Anticoll()
    
                # If we have the UID, continue
                if status == MIFAREReader.MI_OK:
                    # This is the default key for authentication
                    key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
                    # Select the scanned tag
                    MIFAREReader.MFRC522_SelectTag(uid)
                    # Authenticate
                    status = MIFAREReader.MFRC522_Auth(MIFAREReader.PICC_AUTHENT1A, 8, key, uid)
                    # Check if authenticated
                    if status == MIFAREReader.MI_OK:
    
                        MIFAREReader.MFRC522_Read(8)
                        self.stateChanged.emit(MainWindow.state1)
                        # send data via signal
                        self.infoChanged.emit(MIFAREReader.tagId, MIFAREReader.tagName, MIFAREReader.tagDetails)
                        time.sleep(3)
                        MIFAREReader.MFRC522_StopCrypto1()
                        self.stateChanged.emit(MainWindow.state2)
    
                    else:
                        self.stateChanged.emit(MainWindow.state3)
                        time.sleep(2)
                        self.stateChanged.emit(MainWindow.state4)
    
    
    if __name__ == "__main__":
        import sys
        app = QtGui.QApplication(sys.argv)
        w = MainWindow()
        w.show()
        sys.exit(app.exec_())