信号和槽
基础知识
信号函数定义
class XX:public QObject{
Q_OBJECT // 宏定义,用来处理语法扩展
signals://信号函数
void signal_func(……);//只声明,不定义
};
槽函数定义
class xx:public QObject{
Q_OBJECT
public slots: //用于标记
void slot_func(……){
pass;//槽函数的内容
}
};
槽函数不仅可以连接在某个信号上,对信号作出反应,也可以作为普通的成员函数被对象调用
槽函数和信号的连接
利用QObject基类的connect函数
示例:
/*
connect 函数的参数
sender:信号发送对象指针,QObject *
signal:要发送的信号函数,char *
receiver:信号的接收对象指针 QObject *
method:执行的槽函数,char*
*/
//需求:button负责关闭lable
//buttonquit负责退出应用程序
int main(int argc, char *argv[])
{
//创建应用程序对象
QApplication a(argc, argv);
QTranslator translator;
const QStringList uiLanguages = QLocale::system().uiLanguages();
for (const QString &locale : uiLanguages) {
const QString baseName = "first_proj_" + QLocale(locale).name();
if (translator.load(":/i18n/" + baseName)) {
a.installTranslator(&translator);
break;
}
}
QDialog parent;
//parent.move(500,80);
parent.resize(400,500);
QLabel label("我是label",&parent);
QPushButton button("点击关闭label",&parent);
label.resize(200,100);
button.resize(100,100);
label.move(150,100);
button.move(150,300);
//信号和槽
//点击按钮关闭标签
//button 的信号:clicked
//label 的槽函数:close
//button 实现了关闭label的功能
QObject::connect(&button,SIGNAL(clicked()),&label,SLOT(close()));
//点击按钮退出程序
QPushButton buttonquit("退出",&parent);
buttonquit.move(150,450);
//buttonquit 实现了退出app的功能
QObject::connect(&buttonquit,SIGNAL(clicked()),&a,SLOT(closeAllWindows()));
parent.show();
//消息循环机制:
return a.exec();
}
注意点
- 信号函数和槽函数的参数要一致,信号函数的参数会传给槽函数,最终触发槽函数的运行,实现想要的功能。
- 槽函数可以带有缺省参数
QObject::connect(A,SIGNAL(sigfun(int)),B,SLOT(slotfun(int,int = 0)));
- 信号函数的参数可以多余槽函数,会被忽略
QObject::connect(A,SIGNAL(sigfun(int,int),B,SLOT(slotfun(int)));
- 信号和槽连接对应关系
- 一个信号对应多个槽,但是槽函数的执行顺序不确定
- 多个信号对应一个槽,无论哪个信号发送了,都会触发槽函数的执行。若是信号都被触发,槽函数会被触发多次。
- 两个信号可以直接连接,表示消息的传递
//一对多
QObject::connect(A,SIGNAL(sigfun(int),B1,SLOT(slotfun1(int)));
QObject::connect(A,SIGNAL(sigfun(int),B2,SLOT(slotfun2(int)));
//多对一
QObject::connect(A1,SIGNAL(sigfun1(int),B,SLOT(slotfun(int)));
QObject::connect(A2,SIGNAL(sigfun2(int),B,SLOT(slotfun(int)));
//消息传递
QObject::connect(A1,SIGNAL(sigfun1(int)),A2,SIGNAL(sigfun2(int)));
实例:滑块和选值框的同步
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QDialog parent;
parent.resize(500,500);
//创建滑块
QSlider slider(Qt::Horizontal,&parent);
slider.move(100,100);
//选择框
QSpinBox spinbox(&parent);
spinbox.move(100,200);
//设定range,但要保持同步
slider.setRange(0,500);
spinbox.setRange(0,500);
//建立同步关系
QObject::connect(&slider,SIGNAL(valueChanged(int)),&spinbox,SLOT(setValue(int)));
QObject::connect(&spinbox,SIGNAL(valueChanged(int)),&slider,SLOT(setValue(int)));
parent.show();
return a.exec();
}