Daniel Frost
Daniel Frost

Reputation: 51

Running multiple functions in PyQt5

I'm trying to run the printer function at the same time as the loopRun function but once I run the code (just as it is now) it first runs the printer functions and then loads up the GUI and does the loopRun function. I tried multi-processing in the syncFunctions function but it gives me an error. What is the best way to run them together? (This is a small scale code of my actual code so I'm hoping to find a way that would almost always work) Btw multithreading didn't work either.

import sys
import time
import multiprocessing
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtCore import QTimer

# ----------------------------------------------------

def syncFunctions(func1, args1, func2, args2, optional = None):

    p1 = multiprocessing.Process(target = func1, args = args1)
    p2 = multiprocessing.Process(target = func2, args = args2)


    if __name__ == "__main__":

        p1.start()
        p2.start()
        p1.join()
        p2.join()


def singleRun(pb, timer):

    pb.setValue(pb.value() + 1)

    if pb.value() >= pb.maximum():

        timer.stop()


def loopRun(pb, delay):

    timer = QTimer(window)
    timer.start(delay)
    timer.timeout.connect(lambda: singleRun(pb, timer))


def printer(num):

    for i in range(num):

        print(i)

# ----------------------------------------------------

app = QApplication(sys.argv)
window = QWidget()
window.setWindowTitle("Window")
window.setFixedWidth(1000)
window.setFixedHeight(600)
window.move(100, 50)

window.setStyleSheet(
    "background-color: rgb(208, 208, 208);"
)


ProgressBar1 = QtWidgets.QProgressBar(window)
ProgressBar1.setGeometry(400, 50, 200, 24)
ProgressBar1.setProperty("value", 0)
ProgressBar1.setStyleSheet(
    "QProgressBar {"
    "background-color: rgb(0, 33, 68);"
    "font: 11pt \'Trebuchet MS\';"
    "font-weight: bold;"
    "color: rgb(255, 75, 20);"
    "text-align: center;"
    "border: 1px solid;"
    "border-color: rgb(195, 195, 195);"
    "}"
    "\n"
    "QProgressBar:chunk {"
    "background-color: rgb(245, 219, 15);"
    "}"
)


loopRun(ProgressBar1, 25)
printer(100)

# syncFunctions(loopRun, [ProgressBar1, 25], printer, [100])


window.show()
sys.exit(app.exec_())

Upvotes: 0

Views: 644

Answers (1)

eyllanesc
eyllanesc

Reputation: 243897

You should not use multiprocessing with Qt since QObjects are not pickable so they do not allow to use this functionality. In this case it is better to use threads. On the other hand, printing 100 numbers is very fast, so the effect that the user will observe is that it is done before the GUI is shown, so it is better to create a small delay.

import sys
import time
import threading

from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QApplication, QProgressBar, QWidget


def singleRun(pb, timer):
    pb.setValue(pb.value() + 1)
    if pb.value() >= pb.maximum():
        timer.stop()


def loopRun(pb, delay):
    timer = QTimer(window)
    timer.start(delay)
    timer.timeout.connect(lambda: singleRun(pb, timer))


def printer(num):
    for i in range(num):
        print(i)
        time.sleep(0.1)


app = QApplication(sys.argv)
window = QWidget()
window.setWindowTitle("Window")
window.setFixedWidth(1000)
window.setFixedHeight(600)
window.move(100, 50)

window.setStyleSheet("background-color: rgb(208, 208, 208);")


ProgressBar1 = QProgressBar(window)
ProgressBar1.setGeometry(400, 50, 200, 24)
ProgressBar1.setValue(0)
ProgressBar1.setStyleSheet(
    "QProgressBar {"
    "background-color: rgb(0, 33, 68);"
    "font: 11pt 'Trebuchet MS';"
    "font-weight: bold;"
    "color: rgb(255, 75, 20);"
    "text-align: center;"
    "border: 1px solid;"
    "border-color: rgb(195, 195, 195);"
    "}"
    "\n"
    "QProgressBar:chunk {"
    "background-color: rgb(245, 219, 15);"
    "}"
)


loopRun(ProgressBar1, 25)
threading.Thread(target=printer, args=(100,), daemon=True).start()


window.show()
sys.exit(app.exec_())

Upvotes: 2

Related Questions