0

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

1 Answer 1

2

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_())
Sign up to request clarification or add additional context in comments.

5 Comments

This works, thanks! Quick question though. I tried running multiple functions (including GUI ones that include PyQt) but it doesn't work. Is there any way I can run multiple GUI functions (up to three maybe)?
@DanielFrost What is GUI functions? without context it is impossible to help you. Please understand my answer before trying anything else.
I did understand your answer. I tried it and it works but I might have to do the same things with two or more functions like loopRun that has something to do with the GUI and PyQt. Whenever I try threading with these functions I get an error.
@DanielFrost Have I used threading in loopRun? Well no, because the widgets cannot and should not be executed in another thread, and loopRun does not execute any time-consuming functions, so a QTimer is sufficient.
Oh alright, I get it now. I tried your answer in my main code and it worked perfectly. You're a lifesaver! I followed you on Twitter btw (but it seems to be inactive lol)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.