赞
踩
#ifndef SETDIALOG_H #define SETDIALOG_H #include <QDialog> namespace Ui { class setdialog; } class setdialog : public QDialog { Q_OBJECT public: explicit setdialog(QWidget *parent = nullptr); ~setdialog(); private slots: void on_btnAdd_clicked(); signals: void sig_addOne(int value); private: Ui::setdialog *ui; }; #endif // SETDIALOG_H
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); private slots: void on_btnOpen_clicked(); private: Ui::Widget *ui; }; #endif // WIDGET_H
#include "setdialog.h" #include "ui_setdialog.h" setdialog::setdialog(QWidget *parent) : QDialog(parent) , ui(new Ui::setdialog) { ui->setupUi(this); } setdialog::~setdialog() { delete ui; } void setdialog::on_btnAdd_clicked(){ static int score=100; emit sig_addOne(score++); }
#include "widget.h" #include "ui_widget.h" #include <setdialog.h> Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); } Widget::~Widget() { delete ui; } void Widget::on_btnOpen_clicked(){ setdialog dlg; connect(&dlg ,&setdialog::sig_addOne,[=](int value){ ui->lineEdit_score->setText(QString::number(value)); }); dlg.exec(); }
#ifndef CHILDTHREAD_H #define CHILDTHREAD_H #include <QThread> using namespace std; #include <string> struct Score{ string name; int id; int age; }; class ChildThread : public QThread { Q_OBJECT public: ChildThread(); signals: void sig_SendToUI(Score score); protected: void run() override; }; #endif // CHILDTHREAD_H
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <childthread.h> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); private slots: void on_btnUpdate_clicked(); void showInfo(Score s); private: Ui::Widget *ui; }; #endif // WIDGET_H
#include "childthread.h" #include <QDebug> ChildThread::ChildThread() {} void ChildThread::run(){ Score s; s.name="Jack"; s.age=18; s.id=10086; emit sig_SendToUI(s); qDebug()<<"ui thread id4_run = "<<QThread:: currentThreadId(); }
#include "widget.h" #include "ui_widget.h" #include <QDebug> #include <childthread.h> Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); } Widget::~Widget() { delete ui; } void Widget::on_btnUpdate_clicked(){ qDebug()<<"正常运行"; ChildThread* ch=new ChildThread; connect(ch,&ChildThread::sig_SendToUI,this,&Widget::showInfo); ch->start(); qDebug()<<"ui thread id2_btnUpdate = "<<QThread:: currentThreadId(); } void Widget::showInfo(Score s){ string info="name="+s.name+" id="+to_string(s.id)+" age="+to_string(s.age); ui->lineEdit->setText(QString::fromStdString(info)); qDebug()<<"ui thread id3_showInfo = "<<QThread:: currentThreadId(); }
跨UI发送信号是指在不同用户界面组件之间传递信息,以实现交互和数据共享。
Qt的信号和槽机制是跨UI组件通信的经典方法。信号和槽允许对象之间进行松耦合的通信:
信号:由对象发出,表示某个事件发生。
槽:可以是任何可调用对象,当信号发出时,槽会被调用。
连接:通过QObject::connect方法将信号和槽连接起来。
void Widget::on_btnOpen_clicked(){
setdialog dlg;
connect(&dlg ,&setdialog::sig_addOne,[=](int value){
ui->lineEdit_score->setText(QString::number(value));
});
dlg.exec();
}
这是一个槽函数,用于响应名为 btnOpen 的按钮点击事件。Widget 是一个自定义的类,包含这个槽函数。
这里创建了一个 setdialog 类型的对象 dlg。
这行代码使用了 Qt 的信号和槽机制,建立了一个连接:
&dlg 是信号发送者,即 setdialog 对象。
&setdialog::sig_addOne 是 setdialog 类中的一个信号。
[=](int value){ … } 是一个Lambda表达式,作为槽函数。当信号 sig_addOne 发出时,这个Lambda函数会被调用,接收一个整数参数 value。
ui->lineEdit_score->setText(QString::number(value)); 将接收到的 value 转换为字符串,并设置到 lineEdit_score 控件中显示。
这行代码以模态方式运行对话框 dlg。exec() 函数会阻塞,直到对话框关闭。
执行事件循环.
void setdialog::on_btnAdd_clicked(){
static int score=100;
emit sig_addOne(score++);
}
代码解析
这是一个槽函数,用于响应 setdialog 类中名为 btnAdd 的按钮点击事件。
声明并初始化一个静态局部变量 score,初始值为 100。
静态局部变量在函数调用之间保持其值不变。也就是说,每次调用这个函数时,score 的值都会在上一次调用的基础上增加,而不会每次重新初始化为 100。
emit 关键字用于发出信号。这里发出的是 sig_addOne 信号。
score++ 是后置递增运算符,意味着在发出信号时,score 的当前值将被使用,然后 score 自增 1。
例如,第一次点击按钮时,score 的值是 100,信号 sig_addOne 发出时传递的值是 100,然后 score 增加到 101。
下一次点击按钮时,score 的值是 101,信号 sig_addOne 发出时传递的值是 101,然后 score 增加到 102。
信号和槽的工作流程
当用户点击 btnAdd 按钮时,on_btnAdd_clicked() 函数会被调用。
该函数发出 sig_addOne 信号,并传递当前的 score 值。
score 值会在每次按钮点击后递增,因此每次发出的信号都会传递一个增加后的 score 值。
在主窗口的槽函数中(如之前提到的 on_btnOpen_clicked()),连接到 sig_addOne 信号的槽函数会接收到这个 score 值,并在界面上更新显示。
void ChildThread::run(){
Score s;
s.name="Jack";
s.age=18;
s.id=10086;
emit sig_SendToUI(s);
qDebug()<<"ui thread id4_run = "<<QThread:: currentThreadId();
}
这是 ChildThread 类的 run 方法,是线程的入口点。在 QThread 中,run 方法会在调用 start 后在子线程中执行。
创建一个 Score 类型的对象 s。Score 可能是一个自定义的数据结构或类。
设置 Score 对象 s 的 name 属性为 “Jack”。
设置 Score 对象 s 的 age 属性为 18。
设置 Score 对象 s 的 id 属性为 10086。
发出信号 sig_SendToUI,并传递 Score 对象 s。
sig_SendToUI 是 ChildThread 类中的一个自定义信号,用于将数据传递到主线程的UI组件中进行显示或处理。
输出当前线程的线程ID,使用 qDebug() 进行调试打印。
QThread::currentThreadId() 返回当前线程的ID,可以用来验证代码是在子线程中执行的。
通过这种方式,子线程可以安全地将数据传递到主线程,并在UI中进行显示或处理。
void Widget::on_btnUpdate_clicked(){
qDebug()<<"正常运行";
ChildThread* ch=new ChildThread;
connect(ch, &ChildThread::sig_SendToUI, this, &Widget::showInfo);
ch->start();
qDebug()<<"ui thread id2_btnUpdate = "<<QThread::currentThreadId();
}
这是一个槽函数,用于响应 btnUpdate 按钮的点击事件。
使用 qDebug() 输出调试信息,表示槽函数已被正确调用。
动态创建一个 ChildThread 对象 ch。ChildThread 类继承自 QThread,它代表一个独立的执行线程。
使用 Qt 的信号和槽机制,将子线程 ch 的 sig_SendToUI 信号连接到当前对象(Widget 类实例)的 showInfo 槽函数。
sig_SendToUI 是 ChildThread 类中定义的一个信号。
showInfo 是 Widget 类中的一个槽函数,用于处理来自子线程的数据并更新UI。
调用 ch 的 start() 方法启动子线程。start() 方法会调用 ChildThread 类中的 run() 方法,在子线程中执行其中的代码。
使用 qDebug() 输出当前线程的线程ID,帮助开发者确认代码在主线程中执行。
**创建并启动子线程:**当用户点击 btnUpdate 按钮时,程序会动态创建一个 ChildThread 对象并启动子线程。
**连接信号和槽:**将子线程的信号 sig_SendToUI 连接到主线程的槽函数 showInfo。这样,当子线程发出信号时,主线程的槽函数会被调用,以更新UI。
**调试输出:**输出调试信息,确认槽函数被调用和线程ID。
最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。
同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。
谢谢您的支持,期待与您在下一篇文章中再次相遇!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。