Does Pyqt5 monitor events asynchronously on Windows and synchronously on Raspberry?

Asked

Viewed 41 times

1

Context

I’m developing a program that uses Opencv4 to identify some metal fasteners, the program is relatively simple and uses in short color search contour filters, in Windows so far everything runs as desired, however I have to do the portability for the Raspberry Pi3, after a few days solving installation problems of Python3.9, Opencv4.4 and PYQT5, I was able to run the code and display the main screen of the application, and the others 'usually'.


Problem

In Windows, when I set a trigger that triggers a function in the class I am in, it ALWAYS can be triggered, no matter if the function that is running is in a 'while', 'Sleep', 'for' or anything else, then when I click the 'Start' button it triggers the 'onClicked() function'that is kept in a 'while' updating the image with the 'displayImage()', but if I click, for example, the 'Stop' button it passes to the 'Onclicked' function the 'False' parameter that breaks the 'while'. (Probably not the best way to do it, but it works).

In Raspberry when my function 'onCliked()' is triggered and enters into the 'while' all the rest of the program to respond, as if the events were no longer monitored, but do not understand why this happens, the code is the same, the operation should be the same right?. How do I make events be monitored at all times on Raspberry?.

Since the code is great I had to cut some parts, but you can see the full in my repository.

class MainWindow(QMainWindow):

    # Define o LayOut e a(s) ação(es) de cada gatilho(s).
    def __init__(self):
        super(MainWindow, self).__init__()
        loadUi("Ui/mainWindow.ui", self)
        self.PhotoPath.setText(os.path.normpath(os.path.join(os.path.dirname(__file__), '../Images/')))
        # Associando as classes de outras janelas a um objeto correspondente.
        self.JsonWindow = JsonTree()
        self.ControllerWindow = MachineController()
        self.PopUpWindow = PopUp()

        # Conecta o botão de inicio á execução do programa de identificação.
        self.Start.clicked.connect(
            lambda checked: self.onClicked(True)
        )

        # Conecta o botão de Saida com a função que finaliza a execução do programa.
        self.Stop.clicked.connect(
            lambda checked: self.onClicked(False)
        )

Function that is called when I press the "Start" button. (I cut some pieces to post here)

    def onClicked(self, FDs):
    global cap, img, nominalIndex, Processo
    Processo = FDs
    if Processo:
        last = self.janela

    # Mantem o processo rodando.
    while Processo:

            lower = np.array([
                self.h_min.value(),
                self.s_min.value(),
                self.v_min.value()
            ])
            upper = np.array([
                self.h_max.value(),
                self.s_max.value(),
                self.v_max.value()
            ])
            msk = Op.refineMask(Op.HSVMask(edge_analyze, lower, upper))
            cv2.rectangle(msk, (0, 0), (msk.shape[1], msk.shape[0]), (0, 0, 0), thickness=20)
            chr_k = cv2.bitwise_and(edge_analyze, edge_analyze, mask=msk)

       
        self.displayImage(chr_k, 1)
        cv2.waitKey(1)

Function responsible for displaying the image in my 'Qlabel'. (I cut some pieces to post here)

    def displayImage(self, imgs, window=1):
        qformat = QImage.Format_Indexed8
        if self.janela == zProcess and not self.LiveS.isChecked():
            imgs = cv2.resize(imgs, None, fx=0.25, fy=0.25)
        if len(imgs.shape) == 3:
            if (imgs.shape[2]) == 4:
                qformat = QImage.Format_RGBA888
            else:
                qformat = QImage.Format_RGB888
        imgs = QImage(imgs, imgs.shape[1], imgs.shape[0], qformat)
        imgs = imgs.rgbSwapped()
        self.imgLabel.setPixmap(QPixmap.fromImage(imgs))
        self.imgLabel.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)

Demonstration of Operation in both Systems:

Raspberry Pi3 with 2021 standard OS: Raspberry para de responder após a imagem ser exibida


Windows 10: Programa não trava no Windows

This is my first question asked here at the STOF, so in case something has not become clear or may improve please let us know.

  • 1

    Hello @Henrycke B.S, I know the question was asked some time ago, but just to explain: what happened here is that you need to execute all the logic of the function onClicked in a separate thread, otherwise the thread on which the interface is running is blocked by this function and the interface is no longer responsive. This is true for both Windows and Raspberry Pi (or any other OS). What must have happened is that in Windows running is fast enough for you not to notice the program failing to get responsive.

  • 1

    Um, I had not taken into account the speed of processing, I find it strange to get so discrepant but it makes sense, anyway, I ended up separating this and other processes into other threads and worked "well" unfortunately I started having problems with "segmentation failure" on Raspberry, and I decided to change the whole interface to web soon. Thank you for your attention @jfaccioni <3

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.