QT学习笔记和踩坑记录(第一天)

QT学习笔记:

0001 注释的快捷键

​ Ctrl+/ 可以多行注释或者取消注释。

0002 查看帮助文档

​ F1跳转到要查看的代码的帮助文档,在按一次F1,展开帮助文档。

0003 Q_UNUSED

​ Q_UNUSED(变量)可以让没被使用的变量不报令人讨厌的警告。

0004 Q_OBJECT

​ 只有继承了QObject类的类,才具有信号槽的能力。所以,为了使用信号槽,必须继承QObject。凡是QObject类(不管是直接子类还 是间接子类),都应该在第一行代码写上Q_OBJECT。

0005 setParent()

​ 如果不指定父对象,对象和对象(窗口和窗口)没有关系,独立

​ a指定b为它的父对象,a就会放在b的上面,即a成为b的子控件。

​ 指定父对象,有两种方式:

​ 1)a.setParent(b)

​ 2)通过构造函数传参,即在实例a的时候将b做为它的参数传进去

​ 只需要父对象b显示,上面的子对象a自动显示。

0006 QPainter绘图

​ QPainter绘图的时候,原点在左上角,向右下方绘图,可以通过painter.translate()和painter.rotate()函数改变原点位置和旋转图形。

0007 qDebug

​ 头文件QDebug,qDebug函数可用于打印某些变量的值,与cout的用法一样,一般用于调试。

0008 connect函数详解

​ connect函数用于将一个信号和槽函数相关联,当信号触发时调用该槽函数,两者可以位于不同的类。

QT4的connect函数详解:

​ 函数定义:connect(Sender,SIGNAL(signal),Receiver,SLOT(slot));

Sender是信号的发送者,如当一个按钮被点击时要发射点击的信号,那么发送者就是这个按钮本身。

​ **SIGNAL(signal)**是信号名,可以是自定义的信号,也可以是QT自带的信号。

Receiver是信号的接收者、槽函数的拥有者。

​ **SLOT(slot)**是需要调用的槽函数,即使是在当前类中,也需要加类名限定该函数。

​ 可能出现的问题

QT4的connect函数实际上利用SIGNALSLOT这两个宏,把其后的函数名转换成一个字符串。随后,moc 将会扫描 全部文件,将所有的 signal 和 slot 提取出来做成一个映射表。QObject::connect()函数则会从这个映射表里面找到该·· 字符串,从 signal 的名字就可以找到 slot 的名字,因此也就知道了在 signal emit 的时候,该去调用哪一个 slot 函数。

​ 1)没有编译期检查:因为函数名被处理成字符串,所有的检查都是在运行时完成的。这就是为什么有时会发生编译通过 了,但 slot 并没有被调用。此时,你就应该去检查 console 的输出,看看有没有什么 warning 说明 connect 并没有成功。

​ 2)因为处理的是字符串,所以 slot 中的类型名字必须用 signal 的完全一致,而且在头文件中的和实际 connect 语句中的 也必须一致。也就是说,如果你使用了 typedef 或者 namespace,connect 就可能不成功(在 Qt 5 之前的版本中,我们当 然也可以使用namespace,但是必须保证头文件中的和 connect 语句中的文本完全一致)。

QT5的connect函数详解:

​ 函数定义:connect(sender, &Sender::valueChanged, receiver, &Receiver::updateValue);

​ 各个参数与之前的类似,优点是可以连接到任意函数,缺点是在使用重载的信号和函数的时候得定义函数指针

​ 例子:

connect(&sm->clicked_big_window,&QPushButton::pressed,this,&MainWidget::toBigWindow);

​ sm是前面的一个实例,将sm中的clicked_big_window按钮作为信号的发送者,当发射QPushButton::pressed信号, 即按钮被点击的信号时,调用当前对象的(this)的,&MainWidget::toBigWindow函数。

0009 signals信号详解

​ signals信号详解:

​ 1)信号必须有signals关键字来声明

​ 2)信号没有返回值,但可以有参数

​ 3)信号就是函数的声明,只需声明,无需定义

​ 4)使用:emit mySiganal()

​ 5)信号可以重载

​ 例子:

signals:
	void mySignal();
	void mySignal(int,QString);

​ 6)信号重载的时候,为了QT5的connect函数不产生二义性(报错),需在connect之前定义该信号的函数指针,用该函数指针代替 connect的第二个参数

​ 如:

//无参的mySignal
void (XXXX::*funSignal)()=&XXXX::mySignal;
connect(&XXXX,funSignal,XXXX,&XXXX::XXXX);
//有参的mySignal
void (XXXX::*testSignal)(int ,QString)=&XXXX::mySignal;
connect(&xxxx,funSignal,XXXX,&XXXX::XXXX);

0010 QT中的Lambda表达式

​ Lambda表达式是C++11新增的新特性,想在QT中使用的话,得在项目文件(.pro)中加入 CONFIG += C++11

QPushButton *b= new QPushButton(this);
b->setTest("Lambda表达式");
connect(b,&QPushButton::released,
		[b]()//匿名内部类
		{
			//此处相当于槽函数
            b->setTest("Lambda表达式2");
		}
		)
/*
  []的作用是将外部的变量,以值传递的方式传递进这个匿名内部类
  [=]表示把外部所有局部变量、勒种所有成员传进去
  []() mutable 表示对外部变量不仅可读还可写
*/

0011 坐标系统

​ 主窗口相对于屏幕、子控件相对于父窗口,坐标系统的原点在左上角。

0012 内存回收机制

​ 1)指定父对象后

​ 2)直接或间接继承于QObject

​ 子对象如果是动态分配空间(new)的话,不需要手动释放(delete),系统会自动释放,即该子对象的析构函数会被自动调用。

QT踩坑记录:

0001

​ QT任何路径下都不能出现中文、空格 。

0002

​ 注释只能用//,/**/会报错。

0003

​ error: LNK2001: 无法解析的外部符号 “public: virtual struct QMetaObject const * __cdecl

​ 解决办法:

​ 编译出错是因为没有生成moc_mainwindowprivate.cpp文件造成的。

​ 如果新添加QObject派生类到您的项目,则必须再次运行qmake,即
1、清理项目(非必须)
​ 2、运行qmake(必须)
3、构建项目(必须)
​ 否则,如果在QObject继承的类上进行增量构建,那么您将拥有过时的moc文件,或者干脆没有moc文件。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值