关于Qt的信号槽原理很多大佬都有介绍,这里不再班门弄斧,在这里侧重介绍信号槽的一些实际应用。
信号连接槽
在初始化的时候将信号槽的连接建立好,当发送方的信号被触发(属性或事件发生了变化)时,在槽函数中作出相应的处理即可,这是最常见的应用。 举个小例子:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//连接信号槽,处理按钮点击事件
connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(onButtonClicked()));
}
MainWindow::~MainWindow()
{
delete ui;
}
//槽函数 - 响应按钮点击事件
void MainWindow::onButtonClicked()
{
//弹窗
QMessageBox::information(this, "signal and slot", "button clicked!");
}
我们来看一下运行效果:
Qt对象有哪些信号,可以打开Qt助手自行查阅。QPushButton的帮助文档中没有看到相关信号,就从QAbstractButton基类中去查, QPushButton的能够发出的信号如下:
void
clicked(bool checked = false)
void
pressed()
void
released()
void
toggled(bool checked)
信号连接多个槽
当发送方的信号被触发时,需要多方进行处理的时候就用到了“信号连接多个槽”。举个例子:
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTextEdit>
#include "savetextthread.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//保存文本线程
SaveTextThread *save_thread = new SaveTextThread(this);
//信号:文本发生改变 -> 槽:显示编辑信息
connect(ui->textEdit, SIGNAL(textChanged()), this, SLOT(onTextChanged()));
//信号:文本发生改变 -> 槽:在线程中保存文件
connect(ui->textEdit, SIGNAL(textChanged()), save_thread, SLOT(saveText()));
}
MainWindow::~MainWindow()
{
delete ui;
}
//槽函数 - 显示编辑信息
void MainWindow::onTextChanged()
{
int len = ui->textEdit->toPlainText().length();
int row = ui->textEdit->textCursor().blockNumber() + 1;
int col = ui->textEdit->textCursor().columnNumber() + 1;
ui->statusbar->showMessage(QString().sprintf("文本长度:%d 当前位置 行:%d 列:%d", len, row, col));
}
savetextthread.cpp :
#include "savetextthread.h"
#include <QTextEdit>
#include <QTimer>
SaveTextThread::SaveTextThread(QObject* parent): QThread(parent)
{
stop_flag = true;
}
SaveTextThread::~SaveTextThread()
{
stop();
quit();
wait();
}
void SaveTextThread::stop()
{
stop_flag = true;
}
//槽:在线程中保存文件
void SaveTextThread::saveText()
{
QTextEdit* edit = (QTextEdit*)sender();
if (!edit){
return;
}
//获取文本
m_str = edit->toPlainText();
stop_flag = false;
//运行线程
runThreadGracefully();
}
void SaveTextThread::runThreadGracefully()
{
if (stop_flag) {
return;
}
if (isRunning()){
//当线程在运行时,进入查询状态,每1000ms执行一次
QTimer::singleShot(1000, this, [=]{ runThreadGracefully(); });
} else {
//运行线程
start();
}
}
void SaveTextThread::run()
{
//保存字符串到文件
QFile file("./test.txt");
if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)){
file.write( qPrintable(m_str) );
file.close();
}
}
我们来看一下运行效果:
在文件中:
其中,QTextEdit对象发出的textChanged信号连接了2个槽函数,为了干了2件事情, 一个是更新显示信息,另一个是保存文本信息。
在SaveTextThread类中,由于没有UI对象, 在槽函数中可以通过sender方法拿到信号发送方的指针。