I hava a PyQt5 GUI app having 2 buttons("read" and "write"). I want to print a word ("read" or"write") 1000000 times when a button is focused. But with the default focus the focus event triggers for first button ("read" in this case) and print "read" 1000000 times before the contents of the GUI render. Can I make the app to trigger the focusIn() event after the contents of the GUI rendered?

from PyQt5 import QtCore, QtWidgets
import sys

class Start_Gui(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Start_Gui, self).__init__(parent)
        self.setGeometry(200, 100, 500, 250)
        self.setWindowTitle("hi")

        self.button1 = QtWidgets.QPushButton("read", self)
        self.button2 = QtWidgets.QPushButton("write", self)

        self.button1.move(100, 50)
        self.button2.move(100, 100)

        for button in (self.button1, self.button2):
            button.installEventFilter(self)

    def eventFilter(self, obj, event):
        if event.type() == QtCore.QEvent.FocusIn:
            if self.button1 is obj:
                self.instruct('read')
            elif self.button2 is obj:
                self.instruct('write')

        return super(Start_Gui, self).eventFilter(obj, event)

    def instruct(self, type):
        if type == 'read':
            for i in range(1000000):
                print("read")
        if type == 'write':
            for i in range(1000000):
                print("write")

gui_app = QtWidgets.QApplication(sys.argv)
gui = Start_Gui()
gui.show()
gui_app.exec_()

Can anyone help?

1 Answers

2
Isma On Best Solutions

You need to start new threads, I don't know your exact requirements but here is an example:

from PyQt5.QtCore import QObject, pyqtSignal

from PyQt5 import QtCore, QtWidgets
import sys

class Start_Gui(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Start_Gui, self).__init__(parent)
        self.setGeometry(200, 100, 500, 250)
        self.setWindowTitle("hi")

        self.button1 = QtWidgets.QPushButton("read", self)
        self.button2 = QtWidgets.QPushButton("write", self)

        self.button1.move(100, 50)
        self.button2.move(100, 100)

        self.readWorkerThread = None
        self.writeWorkerThread = None
        self.readWorker = None
        self.writeWorker = None

        for button in (self.button1, self.button2):
            button.installEventFilter(self)

    def eventFilter(self, obj, event):
        if event.type() == QtCore.QEvent.FocusIn:
            if self.button1 is obj:
                self._instructRead()
            elif self.button2 is obj:
                self._instructWrite()

        return super().eventFilter(obj, event)

    def _instructRead(self):
        if self.readWorkerThread and self.readWorkerThread.isRunning():
            print('read thread is already running.')
            return

        self.readWorker = InstructWorker('read', 100000)
        self.readWorkerThread = QtCore.QThread()
        self.readWorker.moveToThread(self.readWorkerThread)
        self.readWorkerThread.started.connect(self.readWorker.run)
        self.readWorkerThread.start()

    def _instructWrite(self):
        if self.writeWorkerThread and self.writeWorkerThread.isRunning():
            print('write thread is already running.')
            return

        self.writeWorker = InstructWorker('write', 100000)
        self.writeWorkerThread = QtCore.QThread()
        self.writeWorker.moveToThread(self.writeWorkerThread)
        self.writeWorkerThread.started.connect(self.writeWorker.run)
        self.writeWorkerThread.start()


class InstructWorker(QObject):
    reportProgress = pyqtSignal(int, int)

    def __init__(self, instructType, instructNum):
        super().__init__()

        self._instructType = instructType
        self._instructNum = instructNum

    def run(self):
        self._instruct()

    def _instruct(self):
        for i in range(self._instructNum):
            print('{} {}'.format(self._instructType, i))
            self.reportProgress.emit(i, self._instructNum)
        self.thread().terminate()


gui_app = QtWidgets.QApplication(sys.argv)
gui = Start_Gui()
gui.show()
gui_app.exec_()

Hope it helps.