程序员个人网站开发,网站制作实验报告,建网站找哪个平台好呢,网站建设实验作业QT的信号与槽 文章目录 QT的信号与槽前言一、QT 打印hello QT的dome二、信号和槽机制#xff1f;二、信号与槽的用法1、QT5的方式1. 无参的信号与槽的dome2.带参的信号与槽dome 2、QT4的方式3、C11的语法 Lambda表达式1、函数对象参数2、操作符重载函数参数3、可修…QT的信号与槽 文章目录 QT的信号与槽前言一、QT 打印hello QT的dome二、信号和槽机制二、信号与槽的用法1、QT5的方式1. 无参的信号与槽的dome2.带参的信号与槽dome 2、QT4的方式3、C11的语法 Lambda表达式1、函数对象参数2、操作符重载函数参数3、可修改标示符4、错误抛出标示符5、函数返回值6、是函数体 4.信号与槽的总结5.信号与槽的扩展6. 总结 前言
Qt的信号与槽是控件与控件进行交互的方式。是QT中比较重要的内容。 一、QT 打印hello QT的dome
#include QApplication
#include QWidget
int main(int argc, char *argv[])
{QApplication a(argc, argv);QWidget w;/* 创建一个窗口对象 创建对象会自动调用构造函数 */w.show(); /* 显示窗口 */w.setWindowTitle(hello QT); /* 设置窗口标题 */return a.exec(); /* 一个程序能程序运行 一般都会用死循环 这里相当于while(1) 同时让程序一直执行等待用户操作。等待事件的发生 比如鼠标键盘事件*/
}
现在的操作都在主函数里操作如果代码一多就有点不合适了。在QWidget w 语句会自动调用QWidget的构造函数。放在构造里实现。后面所有的子控件都以这个窗口为中心来扩展。
下面在窗口里添加按钮控件。
mainwidget.h
#ifndef MAINWIDGET_H
#define MAINWIDGET_H
#include QWidget
#include QPushButton
class MainWidget : public QWidget
{Q_OBJECT
public:MainWidget(QWidget *parent 0);~MainWidget();
private:QPushButton b1; /* 在窗口类里定义按钮对象 */QPushButton *b2; /* 在窗口类里定义指针按钮对象 */
};
#endif // MAINWIDGET_Hmainwidget.cpp
MainWidget::MainWidget(QWidget *parent): QWidget(parent)
{b1.setParent(this);b1.setText(按钮1);b1.move(100, 100); /* 移动按钮的位置 默认0,0 */b2 new QPushButton(this);b2-setText(按钮2);this-resize(400, 300); /* 设置窗口的大小 */
}如上代码按钮有指定父对象。 指定父对象的两个方法
setParent(指定的父对象 b1.setParent(this)调用构造函数是指定 b2 new QPushButton(this) this就是当前窗口对象(MainWidget的对象。
指定父对象的好处
Qt有一个机制就是指定父对象后不需要手动释放 new过的内存。指定父对象后跟随父对象显示不需要手动显示。
总结要理解一个类的对象的创建过程才能更好的理解程序的执行顺序。很重要 当在一个类的成员中有类类型的成员变量指针时在构造函数里申请空间。比如上面的 b2 new QPushButton(this);
二、信号和槽机制
信号槽是 Qt 框架引以为豪的机制之一。所谓信号槽实际就是观察者模式。当某个事件发生之后比如按钮检测到自己被点击了一下它就会发出一个点击信号signal。这种发出是没有目的的类似广播。任何控件都可以接收这个信号如果有对象对这个信号感兴趣它就会使用连接connect函数意思是将想要处理的信号和自己的一个函数称为槽slot绑定来处理这个信号。也就是说当信号发出时被连接的槽函数会自动被回调。这就类似观察者模式当发生了感兴趣的事件某一个操作就会被自动触发。这里提一句Qt 的信号槽使用了额外的处理来实现并不是 GoF 经典的观察者模式的实现方式。
二、信号与槽的用法
首先信号与槽函数的连接都是通过connect函数来实现。总共有三种用法。
1、QT5的方式
connect(b1, QPushButton::pressed, this, MainWidget::close) /* b1按钮按下信号触发 窗口接收后关闭窗口 */connect的参数 参数1信号的发送者(指针类型 参数2信号 具体用法 发送者类名信号名 参数3接收者(指针类型 参数4接受者接收到这个信号的处理 具体用法 接收者类名槽函数名 参数5网络模块需要用到这里先不介绍。
总结上面的信号与槽都是系统的系统已经定义好的通过帮助文档就可以查找到。当然也可以自定义的。
1. 无参的信号与槽的dome
mainwidget.h
#ifndef MAINWIDGET_H
#define MAINWIDGET_H#include QWidget
#include QPushButtonclass MainWidget : public QWidget
{Q_OBJECTpublic:MainWidget(QWidget *parent nullptr);~MainWidget();
signals:void signal_1(); /* 自定义一个信号 */public slots:void slot_Print(); /* 自定义槽函数 */void slot_cf();private:QPushButton *button;
};
#endif // MAINWIDGET_Hmainwidget.cpp
#include mainwidget.h
#include QDebugMainWidget::MainWidget(QWidget *parent): QWidget(parent)
{button new QPushButton(this);button-setText(确定);button-move(100, 100);connect(button, QPushButton::pressed, this, MainWidget::slot_cf);connect(this, MainWidget::signal_1, this, MainWidget::slot_Print);
}MainWidget::~MainWidget()
{
}void MainWidget::slot_Print()
{qDebug() 接收到信号;
}void MainWidget::slot_cf()
{emit signal_1();
}总结自定义一个信号与自定义两个槽函数。按钮按下信号触发一个槽 slot_cf。接着在槽里发送自定义信号。接着触发另一个槽slot_Print打印 “接收到信号”。可以看到信号与槽都是没有参数的。
2.带参的信号与槽dome
mainwidget.h
#ifndef MAINWIDGET_H
#define MAINWIDGET_H#include QWidget
#include QPushButtonclass MainWidget : public QWidget
{Q_OBJECTpublic:MainWidget(QWidget *parent nullptr);~MainWidget();
signals:void signal_1(); /* 自定义一个信号 */void signal_1(int data, QString str); /* 带参自定义一个信号 */public slots:void slot_Print(); /* 自定义槽函数 */void slot_Print(int data, QString str); /* 带参自定义槽函数 */void slot_cf();void slot_cf_1();private:QPushButton *button;QPushButton *button_1;
};
#endif // MAINWIDGET_Hmainwidget.cpp
#include mainwidget.h
#include QtDebugMainWidget::MainWidget(QWidget *parent): QWidget(parent)
{button new QPushButton(this);button-setText(信号1);button-move(100, 100);button_1 new QPushButton(this);button_1-setText(信号2);button_1-move(200, 200);connect(button, QPushButton::pressed, this, MainWidget::slot_cf);connect(button_1, QPushButton::pressed, this, MainWidget::slot_cf_1);/* 信号的函数指针 */void (MainWidget::*funSignal_1)() MainWidget::signal_1;void (MainWidget::*funSignal_2)(int, QString) MainWidget::signal_1;/* 槽的函数指针 *//* 因为信号与槽函数都可以函数重载 要用函数指针来区分 *//* slot_Print(int data, QString str) 与 slot_Print() 如果不用槽函数就不知道调用有参的还是无参的slot_Print */void (MainWidget::*funSlot_1)() MainWidget::slot_Print;void (MainWidget::*funSlot_2)(int, QString) MainWidget::slot_Print;connect(this, funSignal_1, this, funSlot_1);connect(this, funSignal_2, this, funSlot_2);
}MainWidget::~MainWidget()
{
}void MainWidget::slot_Print()
{qDebug() 接收到信号;
}void MainWidget::slot_Print(int data, QString str)
{qDebug() data str;
}void MainWidget::slot_cf()
{emit signal_1();
}void MainWidget::slot_cf_1()
{emit signal_1(77, mike);
}总结自定义带参的信号与槽。 按键1 按下调用 slot_Print(int data, QString str) 所以最后对应槽打印的值是77 与 mike。 按键2按下调用slot_Print()
由于信号与槽都可以函数重载带参的与无参的信号与槽会函数名一样在connect里会不知道调用哪一个。所以用到了函数重载。 否则会报如下错误
error: no matching function for call to MainWidget::connect(MainWidget, , MainWidget*, )’ 没有匹配的函数用于调用“mainwidget:connectmainwidget*未解析的重载函数类型mainwidget*已解析的重载功能类型”*
2、QT4的方式
QT4的信号与槽是用两个宏来修饰SIGNAL SLOT。
mainwidget.h
#ifndef MAINWIDGET_H
#define MAINWIDGET_H#include QWidget
#include QPushButtonclass MainWidget : public QWidget
{Q_OBJECTpublic:MainWidget(QWidget *parent nullptr);~MainWidget();
signals:void signal_1(); /* 自定义一个信号 */public slots:void slot_Print(); /* 自定义槽函数 */void slot_cf();private:QPushButton *button;
};
#endif // MAINWIDGET_Hmainwidget.cpp
#include mainwidget.h
#include QDebugMainWidget::MainWidget(QWidget *parent): QWidget(parent)
{button new QPushButton(this);button-setText(确定);button-move(100, 100);connect(button, SIGNAL(pressed()), this, SLOT(slot_cf()));connect(this, SIGNAL(signal_1()), this, SLOT(slot_Print()));
}MainWidget::~MainWidget()
{
}void MainWidget::slot_Print()
{qDebug() 接收到信号;
}void MainWidget::slot_cf()
{emit signal_1();
}总结功能跟QT5无参的信号与槽的功能一样。只是connect用QT4来实现。 QT4的注意事项 1. 信号与槽必须有signals与slots来修饰。如果是槽还要在slots加上修饰符。 2. 如果是带参的信号与槽在SIGNAL里与SLOT里信号与槽不能包含任何的变量名。只能有类型。 3. SIGNAL与SLOT要配套使用。 4. SIGNAL与SLOT是把信号与槽直接转为字符串。如果信号与槽的名字写错。是没有编译错误的。只有在运行时报错。这无疑增加程序员的负担。
3、C11的语法 Lambda表达式
Lambda表达式是匿名槽函数。C11的新特性。配合QT的信号一起使用非常方便。 用法 connect发送者发送者类名::信号 [ ] () { } [ 函数对象参数 ] (操作符重载函数参数) mutable或exception -返回值{函数体} 下面重点介绍上面六部分
1、函数对象参数 2、操作符重载函数参数
中接收信号的参数跟信号的函数原型一致。
3、可修改标示符 4、错误抛出标示符 5、函数返回值 6、是函数体 Lambda的dome
#include mainwidget.h
#include QDebug
MainWidget::MainWidget(QWidget *parent): QWidget(parent)
{button new QPushButton(this);button-setText(确定);button-move(100, 100);/* 简单的Lambda表达式 */connect(button, QPushButton::pressed,[](){qDebug() 信号;});
}4.信号与槽的总结
信号与槽的用法有三种建议优先用QT5的与Lambda表达式的。 信号注意点 1、信号必须在类中声明并且加sigals关键字 没有定义也无返回值。 2、两个同名的信号可以函数重载。用函数指针来区分。 3、发送信号用emit 关键字
槽函数注意点 1、函数名相同可以重载。用函数指针来区分。 2、函数可以是任意的成员函数普通函数全局函数、静态函数。 3、槽函数要与信号一致。没有返回值。
5.信号与槽的扩展 第三点就是信号的扩散
6. 总结
主要介绍了QT中信号与槽的各种用法以及信号与的槽的注意事项。