对象之间的Qt信号导致锁定



如果有人能为我指明正确的方向,我将不胜感激,因为我有点卡住了。我正在尝试编写一个简单的小部件计数器程序,其中按下QPushButton(startButton)会启动一个计数器,该计数器每秒递增一,并在QTextBrowser(outputBox)中显示计数器值。我的第一类主窗口包含startButton和ouputBox。我有一个第二类chronoClass,它从启动按钮插槽接收信号,等待一秒钟,然后递增计数器,并通过信号将值发送回显示计数器值的主窗口插槽,直到这一点正常工作。如果我就此离开(对应于注释out emit-countResume();)在下面的代码中),然后我得到一个计数器,它在每次按下按钮后递增并显示一秒钟的时间滞后。理想情况下,我想从主窗口显示插槽向chronos类插槽发送一个信号countResume(),以迭代计数过程,但它不起作用。我已经通读了在线文档和示例,但我无法深入了解

我尝试的实现如下:

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTextBrowser>
#include <QPushButton>
class QTextBrowser;
class QPushButton;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void countRead(int counter);
void on_startButton_clicked();

private:
Ui::MainWindow *ui;
QTextBrowser *ui_outputBox;
QPushButton *ui_startButton;
signals:
void countResume();
void startbutton();
};
#endif // MAINWINDOW_H

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <unistd.h>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui_outputBox = findChild<QTextBrowser*>("outputBox");
ui_startButton = findChild<QPushButton*>("startButton");
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::countRead(int counter)
{
ui_outputBox -> setText(QString::number(counter));
emit countResume();
}
void MainWindow::on_startButton_clicked()
{
emit startbutton();
}

chronoClass.h

#ifndef CHRONOCLASS_H
#define CHRONOCLASS_H
#include<QWidget>
#include<unistd.h>

class chronoClass : public QWidget
{
Q_OBJECT
public:
chronoClass();
int counter{0};
public slots:
void chronoCount();
signals:
void countChrInc(int counter);
};
#endif // CHRONO_CLASS_H

chronoClass.cpp

#include "chronoClass.h"
chronoClass::chronoClass()
{}
void chronoClass::chronoCount()
{
sleep(1);
counter++;
emit countChrInc(counter);
}

main.cpp

#include "mainwindow.h"
#include <QApplication>
#include "philTimer.h"
#include "chronoClass.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
chronoClass c;
QObject::connect(&w, &MainWindow::countResume,
&c, &chronoClass::chronoCount);
QObject::connect(&c, &chronoClass::countChrInc,
&w, &MainWindow::countRead);
QObject::connect(&w, &MainWindow::startbutton,
&c, &chronoClass::chronoCount);
w.show();
return a.exec();
}

我猜您的信号问题来自chrono类中的sleep(1)函数。它将等待1s,再次运行1Qt事件循环等待1s。所有与GUI的交互都必须在两次睡眠调用之间进行,换句话说:永远不会。

有什么特别的理由让你的计时类而不是QTimer吗?

因为使用QTimer时会变得非常容易。这里有一个例子,只有3个文件

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTextBrowser>
#include <QPushButton>
// That will replace your chrono class
#include <QTimer>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void timeout(); // This is connected to the timer
void on_startButton_clicked();

private:
Ui::MainWindow *ui;
QTextBrowser *ui_outputBox;
QPushButton *ui_startButton;

QTimer timer; // The timer object
int counter; // Hold your counter here
};
#endif // MAINWINDOW_H

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
counter(0)
{
ui->setupUi(this);
ui_outputBox = findChild<QTextBrowser*>("outputBox");
ui_startButton = findChild<QPushButton*>("startButton");
timer.setInterval(1000); // 1000ms => 1s
//That signal is emitted every interval of the timer
connect(&timer, &QTimer::timeout, this, &MainWindow::timeout);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::timeout()
{
counter++;
ui_outputBox -> setText(QString::number(counter));
}
void MainWindow::on_startButton_clicked()
{
counter = 0;
ui_outputBox -> setText("0");
timer.start();
}

main.cpp

#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

无论如何,尽量避免使用sleep函数,当使用像Qt这样的框架时会很痛苦,因为它会阻止主事件循环的运行。试着找到Timers类,每个现代框架都有类似的东西。

希望这能有所帮助!

相关内容

  • 没有找到相关文章

最新更新