简体   繁体   中英

Qt/C++: Checkable button and infinite loop

I'm coding a Qt Gui and I'm trying to implement a new feature, I now the precise result I want to arrive at but not how to code it. I'm trying to add a checkable button that when checked would run a function that would only stop when the button is unchecked, but every second a PaintArea I have on the window would be updated (letting me see how the multiple executions of my function are changing my data). It seem that I'll need to use some QThread objects, but just the part dealing with the button is already counter intuitive to me, I've been trying to play with the autoRepeatDelay and autoRepeatInterval without getting my hand on what they do and how they could be useful to me.

I guess that what I'm trying to code is not really original, would have an idea of the steps to implement it, or an example of a code?

Edit: According to the first answers (thank you for them by the way) my question may not be clear. Putting on the side the thread thing, I'd like to implement an infinite loop that only starts when a pressbutton goes to pressed position (it's a checkable button) and stops only when leaving it. The first version I tried to do (with a while(button->isChecked() loop) would completely freeze as the application would be running the loop, the gui would freeze and the button couldn't be turned off (hence the idea of running it in a separate thread). Voila! I hope it's a clearer formulation. Thank you in advance.

I don't know if I really understand what you want to do, but I will try to answer.

First, you want a Button that send a start & stop info to control a thread. You can use a checkbox to begin. This check box send a signal when its state changes. Connect this signal to a slot that perform start thread and stop according to the boolean sent.

Second, in you thread you need to launch the events loop. After, set a timer that call you repaint after every timeout.

Hope it helped.

PS: take care of execution context with you thread and Qt's objects.

Here's a simple skeleton of something that might work. Without knowing your exact requirements, it may or may not be right for your problem. Hopefully it will give you a few hints that do actually help.

void Ui::buttonPressedSlot(bool checked){
    if (checked){
        Processor *processor = new Processor;
        connect(this, SIGNAL(abortCalculations()), processor, SLOT(abort()), Qt::QueuedConnection);
        connect(processor, SIGNAL(updateNeeded()), this, SLOT(updateGui()), Qt::QueuedConnection);
        QThreadPool::globalInstance()->start(processor);
    } else {
        emit abortCalculations(); // this is a signal in your UI class
    }
}

You can then use the following for your calculations.

class Processor : public QObject, public QRunnable{ // QObject must always be first in multiple inheritance
    Q_OBJECT
public:
    ~Processor();

    void run();

public slots:
    void abort();
    void doCalculations();

signals:
    void updateNeeded(); // connect this to the GUI to tell it to refresh

private:
    QScopedPointer<QEventLoop> loop;
};

Processor::~Processor(){
    abort();
}

void Processor::run() {

    loop.reset(new QEventLoop);

    QTimer timer;
    connect(&timer, SIGNAL(timeout()), this, SLOT(doCalculations()));
    timer.setInterval(1000);
    timer.start();

    loop->exec();
 }

 void Processor::abort(){
    if (!loop.isNull()){
        loop->quit();
    }
 }

 void Processor::doCalculations(){
     // do whatever needs to be done

     emit updateNeeded();
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM