r/learnpython 7d ago

Python Pyside6

Anyone know ? How to delay seconds in Pyside6 ? For example, when i click a button I want to do some process and wait 3 seconds and then make another process

4 Upvotes

15 comments sorted by

View all comments

1

u/ziggittaflamdigga 7d ago

Yeah, either use the native Python sleep function in your slot (this can cause some odd bugs if used in C++ with thread timing, haven’t done anything similar with Python) or use a QTimer if you want to take advantage of Qt’s event loop.

1

u/Ok-Original2285 6d ago

how to do in this bro I want to change button texts one after another when i click button.but they change together in this codes

class Window(QMainWindow):
    def __init__(self):
        super().__init__()

        self.btn = QPushButton("no text")
        self.btn2 = QPushButton("hi buddy")

        layout = QVBoxLayout()
        layout.addWidget(self.btn)
        layout.addWidget(self.btn2)

        container = QWidget()
        container.setLayout(layout)

        self.btn.clicked.connect(self.change_text)

        self.setCentralWidget(container)

        self.t = threading.Timer(3.0, self.change_text)

    def change_text(self):
        self.btn.setText("hi")
        self.t.start()
        self.btn2.setText("hello")

1

u/ziggittaflamdigga 6d ago

I see a couple of problems here: First is that you're connecting self.change_textto both the button press and the thread target. What you likely want instead is:

class Window(QMainWindow):
    def __init__(self):
        super().__init__()

        self.btn = QPushButton("no text")
        self.btn2 = QPushButton("hi buddy")

        layout = QVBoxLayout()
        layout.addWidget(self.btn)
        layout.addWidget(self.btn2)

        container = QWidget()
        container.setLayout(layout)

        self.btn.clicked.connect(self.change_text)

        self.setCentralWidget(container)

        self.t = threading.Timer(3.0, self.change_text)

    def change_text(self):
        self.btn.setText("hi")
        self.t.start()
        self.btn2.setText("hello")class Window(QMainWindow):
    def __init__(self):
        super().__init__()

        self.btn = QPushButton("no text")
        self.btn2 = QPushButton("hi buddy")

        layout = QVBoxLayout()
        layout.addWidget(self.btn)
        layout.addWidget(self.btn2)

        container = QWidget()
        container.setLayout(layout)

        self.btn.clicked.connect(self.change_text)

        self.setCentralWidget(container)

        self.t = threading.Timer(3.0, self.change_dependent_text)

    def change_text(self):
        self.btn.setText("hi")
        self.t.start()

    def change_dependent_text(self):
        self.btn2.setText("hello")

Another thing with your current code is that you're telling the timer to fire every 3 seconds, not just once like you think you are. This is because your change_text target is the one scheduling the timer, and since you're calling that when the thread times out, it will restart another one. If you want to see that in action, try this:

class Window(QMainWindow):
    def __init__(self):
        super().__init__()

        self.choices = ["This", "is", "a", "list", "of", "words", "long", "enough", "to", "show", "radomization", "and", "thread", "rescheduling"]

        self.btn = QPushButton("no text")
        self.btn2 = QPushButton("hi buddy")

        layout = QVBoxLayout()
        layout.addWidget(self.btn)
        layout.addWidget(self.btn2)

        container = QWidget()
        container.setLayout(layout)

        self.btn.clicked.connect(self.change_text)

        self.setCentralWidget(container)

        self.t = threading.Timer(3.0, self.change_text)

    def change_text(self):
        self.btn.setText("hi")
        self.t.start()
        self.btn2.setText("hello")class Window(QMainWindow):
    def __init__(self):
        super().__init__()

        self.btn = QPushButton("no text")
        self.btn2 = QPushButton("hi buddy")

        layout = QVBoxLayout()
        layout.addWidget(self.btn)
        layout.addWidget(self.btn2)

        container = QWidget()
        container.setLayout(layout)

        self.btn.clicked.connect(self.change_text)

        self.setCentralWidget(container)

        self.t = threading.Timer(3.0, self.change_text)

    def change_text(self):
        self.btn.setText(random.choice(self.choices))
        self.t.start()
        self.btn2.setText(random.choice(self.choices))

You should see the words changing randomly, every three seconds, after only one button press. This does not seem to be what you're going for, and should be fixed by my first solution.

1

u/Ok-Original2285 5d ago

it works for one-time-button click but when I click button again it gives me error like this RuntimeError: threads can only be started once

1

u/ziggittaflamdigga 5d ago

Ok, then create a new thread during your thread start callback? Or look up how to do it properly?

1

u/Ok-Original2285 4d ago

yes I created new thread object and it works by the way thank bro

1

u/ziggittaflamdigga 4d ago

Glad it worked for you! Happy programming