Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make push button immediately disabled?

Tags:

python

pyqt


Hello everyone! I've found something strange on QPushButton instance. Oh, first of all, I am using..

  • windows 7
  • python 3.4
  • PyQt5

My test code is...

# coding: utf-8

import sys, time
from PyQt5.QtWidgets import QWidget, QApplication, QPushButton

class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.targetBtn = QPushButton('target', self)
        self.targetBtn.move(100, 100)
        self.targetBtn.clicked.connect(self.sleep5sec)

        self.setGeometry(100, 100, 300, 300)
        self.show()

    def sleep5sec(self):
        self.targetBtn.setEnabled(False)
        time.sleep(5)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

What I want is.. when a user push the target button, the button immediately disabled. But in my code, target button is disabled after sleep(5).

What's wrong with my code?

Thank you for reading my question! Please help!

like image 956
passion053 Avatar asked Nov 27 '15 10:11

passion053


People also ask

How do you make a button disabled after you click it?

1.1 To disable a submit button, you just need to add a disabled attribute to the submit button. $("#btnSubmit"). attr("disabled", true); 1.2 To enable a disabled button, set the disabled attribute to false, or remove the disabled attribute.

How do I disable the button after one click in react?

Use the disabled prop to disable a button in React, e.g. <button disabled={true}>Click</button> . You can use the prop to conditionally disable the button based on the value of an input field or another variable or to prevent multiple clicks to the button.

How do I disable the button after one click flutter?

Flutter pushes declarative UI to its limit in this case. Enable and disable the state of a button resulting from the present of onPressed callback. If the onPressed callback is null , Flutter treat the button as no action hence showing the button in a disabled state.


2 Answers

As suggested in the thread I linked in the comment and @MichalF, python's sleep completely freezes the UI, so it does not let the .setEnabled method to be updated.

In Qt all events are managed with the UI's main thread (which is another worker) and thus, actions like .setEnabled have no immediate effect in the UI (takes a bit to repaint it). Using time.sleep the UI threads freeze and thus, the Qt's main worker doesn't update (repaint) de UI until the timer is ended.

A way to change it is by using PyQt5.QtCore.QTimer:

def sleep5sec(self):
    self.targetBtn.setEnabled(False)
    QTimer.singleShot(5000, lambda: self.targetBtn.setDisabled(False))

The above example would instantly disable targetBtn and after 5 second it will re-enable it again.

like image 56
Imanol Luengo Avatar answered Sep 26 '22 00:09

Imanol Luengo


Rule of thumb: DONT USE sleep() IN GUI APPLICATION!

GUI application of almost any kind works in something called event loop, which is single thread mechanism responding to events passed from the operating system (or windows system). If you sleep there, your event loop doesn't work.

When you connected you clicked signal to a method that sleeps inside, the event loop doesn't have a chance to finish signal handling and refresh the image of the interface on the screen, as that happens after the signal is handled. Refreshing graphical elements is done by series of signals send internally.

like image 40
Michał Fita Avatar answered Sep 26 '22 00:09

Michał Fita