我有一个按钮,我想在点击时更改为停止按钮。目前按钮的文本显示“自动触发”,它运行无限循环,单击时文本更改为“停止自动触发”。我的问题是在文本更改后再次单击/按此按钮打破无限循环。
到目前为止代码:
void Cpp_Fire::on_auto_fire_clicked()
{
while(true)
{
ui->auto_fire->setText("Stop Auto Fire");
on_manual_fire_clicked();
}
}
我尝试在上面的循环中插入一个不同的插槽,该按钮在按下按钮后运行(当按钮被释放时它会运行准确)但我无法使其工作。 我知道这可以通过信号/插槽和单独的停止按钮完成,但我不熟悉这种方法,我更喜欢我描述的方法。
答案 0 :(得分:2)
无限循环的问题在于没有其他任何东西可以工作。
您可以使用的一种方法是使用短时间间隔的QTimer来调用on_manual_fire_clicked()方法,然后让on_auto_fire_clicked()方法负责更改按钮上的文本并启用/禁用计时器。
如果你这样做的话,你应该有足够的时间来回应点击等。
编辑:
有关使用QTimer的更多信息,请查看此页面:
或本教程:
http://www.bogotobogo.com/Qt/Qt5_QTimer.php
以下是一些代码:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButton_clicked();
void timerslot();
private:
Ui::MainWindow *ui;
QTimer* myTimer;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QTimer>
#include<QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
myTimer = new QTimer(this);
myTimer->setInterval(500);
myTimer->setSingleShot(false);
connect(myTimer, SIGNAL(timeout()), this, SLOT(timerslot()));
myTimer->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::timerslot()
{
qDebug() << "timeslot";
}
void MainWindow::on_pushButton_clicked()
{
if ( this->myTimer->isActive() == true ) {
this->myTimer->stop();
ui->pushButton->setText("Start");
} else {
this->myTimer->start(500);
ui->pushButton->setText("Stop");
}
}
我希望你能得到这个想法并将其转化为你的需求。
答案 1 :(得分:0)
我完全同意迈克尔的回答。
这也会影响重画! (尝试在应用程序上放置一些窗口,而在无限循环中:你应该看到重绘问题)。
不要使用无限循环,特别是不在插槽内!
尝试 QTimer ,或将对象移至 QThread 。
在这样的循环中:给GUI-Thread一些时间。你可以致电QCoreApplication::processEvents().。但要小心。
QTimer的简单(仍然很差)解决方案可能是: (我发现,迈克尔在他的回答中输入了一个例子。 - 使用它。)。
//have a QTimer 'timer' in the class, and a connect signal
//timer.timeout() to 'onSingleShotFired()'
void Cpp_Fire::on_auto_fire_clicked()
{
if ( ui->auto_fire->text() == "Stop Auto Fire" )
{
timer.stop();
ui->auto_fire->setText("Start Auto Fire");
}
else
{
//MSEC_AUTOFIRE_DELAY is the delay between the autofire-shots
timer.start( MSEC_AUTOFIRE_DELAY );
ui->auto_fire->setText("Stop Auto Fire");
}
}