Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to disable a button after clicking it?
QtWS25 Last Chance

How to disable a button after clicking it?

Scheduled Pinned Locked Moved General and Desktop
14 Posts 9 Posters 23.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    ferdl123
    wrote on last edited by
    #1

    Hello, I would like to have a button which gets disabled as soon as it gets clicked and gets enabled again after the calculations have finished, so the user cannot click on the button several times during the computing process and crash the program.

    @
    void GUI::onCalculate()
    {
    ui->pbCalculate->setEnabled(false);
    ui->pbCalculate->repaint();
    //do calculations which take some time
    ui->pbCalculate->setEnabled(true);
    }
    @

    This doesn't work, because even though the button looks disabled it still performs the event if I click on it again and again.

    This is how I implemented the click-event(clicked() and released() don't solve my problem either):
    @connect(ui->pbCalculate, SIGNAL(pressed()), this, SLOT(onCalculate()));@

    Found "this topic":http://developer.qt.nokia.com/forums/viewthread/4780 but it doesn't quite answer my question, because there is a second button which should be disabled and enabled (which works fine, but that's not what I want). Also I want to avoid using threads for solving this problem.

    Thanks, Ferdl

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SimonL
      wrote on last edited by
      #2

      i would have thought that should work one approach is to disconnect the signal while you are doing your processing and reconnect it
      @
      void GUI::onCalculate()
      {
      disconnect(ui->pbCalculate, SIGNAL(pressed()), this, SLOT(onCalculate()));
      ui->pbCalculate->setEnabled(false);
      ui->pbCalculate->repaint();
      //do calculations which take some time
      ui->pbCalculate->setEnabled(true);
      connect(ui->pbCalculate, SIGNAL(pressed()), this, SLOT(onCalculate()));
      }
      @

      i didn't compile or test that code but it should work.

      1 Reply Last reply
      0
      • F Offline
        F Offline
        ferdl123
        wrote on last edited by
        #3

        Thanks for your reply, but unfortunately this doesn't work either :/

        1 Reply Last reply
        0
        • B Offline
          B Offline
          baysmith
          wrote on last edited by
          #4

          Use a single shot timer to delay the calculation and thus allow the UI to update.

          (Untested code)
          @
          void GUI:onCalculate()
          {
          ui->calculateButton->setEnabled(false);
          QTimer::singleShot(0, this, SLOT(doCalculate()));
          }

          void GUI::doCalculate()
          {
          // do calculations which take some time
          ui->calculateButton->setEnabled(true);
          }
          @

          Nokia Certified Qt Specialist.

          1 Reply Last reply
          0
          • F Offline
            F Offline
            ferdl123
            wrote on last edited by
            #5

            Same result.
            I've uploaded the whole project if someone's interested in this challenge ;)

            "Project Euler Nr. 5":http://www.mediafire.com/?r6rkv94rxbnxavt

            I know it's not that important, but I wanted to make it "uncrashable" and 100% bug-free.

            1 Reply Last reply
            0
            • L Offline
              L Offline
              leon.anavi
              wrote on last edited by
              #6

              Have you tried to perform the calculations in separate thread and to notify the GUI when they are ready?

              http://anavi.org/

              1 Reply Last reply
              0
              • L Offline
                L Offline
                luca
                wrote on last edited by
                #7

                Try this:
                @
                void GUI::onCalculate()
                {
                ui->pbCalculate->setEnabled(false);

                QApplication::processEvents();

                //do calculations which take some time
                ui->pbCalculate->setEnabled(true);
                }
                @

                1 Reply Last reply
                0
                • G Offline
                  G Offline
                  giesbert
                  wrote on last edited by
                  #8

                  I think the problem is another one. The mouse click event that triggeres the first clicked event is currently processed, so the main eventloop is blocked. inside this blocked state, you disable the button (which is no real window, just a widget). The second click event is emitted by mouse to the OS and the OS sends the event to the message loop of the Qt application. It will be send to the widget, when the event loop is entered again, which happens after GUI::onCalculate() is left.

                  So during processing of the event, the widget is not disabled...

                  long calculations should not be done inside the GUI thread so the UI is not blocked. Then this would also not happen, you could trigger some thread, threadpool, QFuture, whatever, disable the button and return. Then the mouse click during the thread is running, will not be processed by the button.

                  Nokia Certified Qt Specialist.
                  Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                  1 Reply Last reply
                  0
                  • F Offline
                    F Offline
                    ferdl123
                    wrote on last edited by
                    #9

                    Okay, looks like there's no way around threads for this. Thanks for the advises and explanation.
                    I'll try it out and report back if I succeed.

                    PS: I forgot to mention that the calculations aren't performed within the GUI class/(thread?).
                    The whole method looks like this:

                    @
                    void GUI::onCalculate()
                    {
                    ui->pbCalculate->setEnabled(false);
                    ui->lwOutput->clear();
                    ui->pbCalculate->repaint();
                    ui->lwOutput->repaint();

                    Euler euler;
                    int j, k, n;
                    n=ui->sbInput->text().toInt();
                    for(k=1; k<=n; k++)
                    {
                        j=euler.calculate(k);
                        ui->lwOutput->addItem(QString::number(k) + ": " + QString::number(j));
                        ui->lwOutput->doItemsLayout();
                        ui->lwOutput->repaint();
                    }
                    
                    ui->pbCalculate->setEnabled(true);
                    

                    }
                    @

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      andre
                      wrote on last edited by
                      #10

                      The calculations are performed in the main thread in the code above. A class does not equal a thread.

                      1 Reply Last reply
                      0
                      • F Offline
                        F Offline
                        ferdl123
                        wrote on last edited by
                        #11

                        [quote author="Andre" date="1307545054"]The calculations are performed in the main thread in the code above. A class does not equal a thread. [/quote]

                        Thanks for clarifying this, I wasn't sure about this hence the question mark.

                        1 Reply Last reply
                        0
                        • F Offline
                          F Offline
                          ferdl123
                          wrote on last edited by
                          #12

                          This piece of code did the trick for me:

                          @
                          GUI::GUI(QWidget *parent) :
                          QMainWindow(parent),
                          ui(new Ui::GUI)
                          {
                          ui->setupUi(this);
                          euler = new Euler();

                          connect(ui->pbCalculate, SIGNAL(clicked()), this, SLOT(onCalculate()));
                          connect(ui->actionExit, SIGNAL(triggered()), qApp, SLOT(quit()));
                          connect(euler, SIGNAL(finished()), this, SLOT(calculationsDone()));
                          

                          }

                          void GUI::onCalculate()
                          {
                          ui->pbCalculate->setEnabled(false);
                          ui->pbCalculate->repaint();
                          ui->lwOutput->clear();
                          ui->lwOutput->repaint();

                          int n;
                          n=ui->sbInput->text().toInt();
                          euler->setN(n);
                          euler->start(QThread::IdlePriority);
                          

                          }

                          void GUI::calculationsDone()
                          {
                          int i;
                          QList<int> results = euler->getResults();

                          for(i=0; i<results.size(); i++)
                          {
                              ui->lwOutput->addItem("Number " + QString::number(results[i]) + " is the smallest number which can be divided evenly by all numbers from 1 to " + QString::number(i+1));
                          }
                          
                          ui->lwOutput->doItemsLayout();
                          ui->lwOutput->repaint();
                          
                          ui->pbCalculate->setEnabled(true);
                          ui->pbCalculate->repaint();
                          

                          }
                          @

                          1 Reply Last reply
                          0
                          • O Offline
                            O Offline
                            ogopa
                            wrote on last edited by
                            #13

                            Actually, this worked perfectly for me:
                            @void wave::on_pushButton_clicked() //Starts program
                            {
                            thread->start();
                            ui->pushButton->setEnabled(false);
                            ui->pushButton_2->setEnabled(true);
                            }

                            void wave::on_pushButton_2_clicked() //Terminates program
                            {
                            thread->terminate();
                            ui->pushButton_2->setEnabled(false);
                            ui->pushButton->setEnabled(true);

                            }@

                            1 Reply Last reply
                            0
                            • D Offline
                              D Offline
                              dangelog
                              wrote on last edited by
                              #14

                              See http://developer.qt.nokia.com/wiki/Threads_Events_QObjects , especially the last examples. If your job is not splittable and/or you can't insert calls to QCoreApplication::processEvents, use a separate thread.

                              Software Engineer
                              KDAB (UK) Ltd., a KDAB Group company

                              1 Reply Last reply
                              0

                              • Login

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved