参考
QT界面开发_哔哩哔哩 (゜-゜)つロ 干杯~-bilibiliwww.bilibili.com接:
juliar:Qt界面开发(1)
juliar:Qt界面开发(2)
一.带参数的信号
前面关于信号signal,我们了解到:
//signals是Qt扩展的关键字
/*信号必须有signals关键字来申明
* 信号没有返回值,但可以有参数
* 信号就是函数的声明,只需声明,无需定义
* 使用:emit mySignal();
*信号可以重载
*/
那下面我们就来看,带参数的信号是怎么样的?
1.首先在subwidget.h中声明(无需定义)一个带两个参数的重载信号函数mySignal
void mySignal(int,QString); //一个整型,一个字符串
2.点击F4,到实现部分,在subwidget.cpp中加入发送的信号:
emit mySignal(250,"我是子窗口");
3.因为信号是给槽函数传参的,所以相应的槽函数也要有两个相应参数,在mainwindow.h定义:
void dealSlot(int,QString);
4.接下来在mainwindow.cpp中进行connect处理
connect(&w,&subWidget::mySignal,this,&MainWindow::dealSlot);
5.mainwindow.cpp中实现槽函数,要打印,需要加入头文件#include <QDebug> (用法同c++中的cin、out)
当信号出现重载时,产生二义性,下面先复习函数指针的用法
函数指针的用法:
对于函数
void fun(int)
{
}
void (*p)(int)=fun //即函数返回值类型 (* 指针变量名) (函数参数列表);
在mainwindow.cpp中使用函数指针的方法进行信号处理
//处理子窗口的信号
void(subWidget::*funSignal)()=&subWidget::mySignal;//&subWidget::mySignal <==> funSignal
connect(&w,funSignal,this,&MainWindow::dealSub);
void(subWidget::*testSignal)(int,QString)=&subWidget::mySignal; //&subWidget::mySignal <==> testSignal
connect(&w,testSignal,this,&MainWindow::dealSlot); //带参数的信号
此外,如果打印的是中文,则需要进行以下编码转换
void MainWindow::dealSlot(int a,QString str)
{
//str.toUtf8() -> 字节数组
//...data() -> QByteArray ->char*
qDebug()<<a<<str.toUtf8().data(); //F1查看其用法:要将中文转成utf8的类型,转化成了char *
}
等到执行一轮循环(切换到子窗口+切换到主窗口),完成,打印出“250 I am main window”可见程序执行正确。
以上是Qt5的代码,若是在Qt4中,作以下修改
public slots: //Qt4槽函数必须有slots关键字来修饰
void myslot(); //与released对应,是一个无参数,无返回值的函数
void changeWin(); //用来隐藏自己,显示对方
void dealSub(); //处理子窗口
void dealSlot(int,QString);
//Qt4信号连接
//Qt4槽函数必须有slots关键字来修饰
connect(&w,SIGNAL(mysignal()),this,SLOT(dealSub()));
connect(&w,SIGNAL(mysignal(int,QString)),this,SLOT(dealslot(int,Qstring)));
//SIGNAL SLOT 将函数名字->字符串不进行错误检查,即函数名错误也编译时也不报错,生成时提示
同样可以。
二.Lambda表达式
Lambda表达式(匿名函数对象)是c++11增加的新特性,在Qt中配合信号一起使用,非常方便,需要在项目文件中添加
CONFIG += C++11 //为了用lambda表达式
Lambda表达式优点:不需要重复调用常函数、连接者
Lambda表达式语法:
QPushButton *b4 = new QPushButton(this);
b4->setText("Lambda");
b4->move(150,150);
int a=10,b=100;
connect(b4,&QPushButton::released,
[=]() mutable
//[]代表函数的开始,用于把外部变量传递进来,
//=指把外部所有局部变量及类中成员以值方式传递进来,要比引用&安全
//this:类中所有成员以值传递方式
//&:把外部所有局部变量,以引用方式传递()不包括类中成员
{ //()指函数的参数、{}代表函数体
b4->setText("123"); //本质上没有改b4,只改了其显示内容
qDebug()<<"11111";
qDebug()<<a<<b; //但是a、b这样的值不能在这儿进行改变(默认是只读),否则会报错,要想对a进行修改,需加关键字mutable(可变的)
a=11;
}
);
三.坐标系统
新建空文件:
mywidget.cpp
#include "mywidget.h"
#include<QPushButton>
myWidget::myWidget(QWidget *parent)
: QWidget(parent)
{
/* 对于父窗口(主窗口),坐标系统相对于屏幕
* 原点:相对于屏幕左上角
* x:往右递增
* y:往下递增)
*/
move(100,100);
/* 对于子窗口,坐标系统相对于父窗口
* 原点:相对于窗口空白区域(不包括边框)
* x:往右递增
* y:往下递增)
*/
QPushButton *b1=new QPushButton(this);
b1->move(100,100);
b1->setText("^_^");
b1->resize(200,200);
QPushButton *b2=new QPushButton(b1);
b2->move(10,10);
b2->setText("@_@");
//b2->resize(100,100);
}
myWidget::~myWidget()
{
}
以上两个按钮b1、b2都是通过new为其动态分配内存空间的,按c++,使用完毕要对其进行内存空间释放,否则容易造成内存泄露。在Qt中,只要1.指定了父对象(有对象树)、2.直接或间接继承于QObject,则自动进行内存释放。
2020.12.28