阜新网站优化,nginx wordpress 伪静态,包头有没有专业做淘宝网站的,做外贸的物流网站有哪些文章目录 一些常见的bug#xff1a;字符集不对产生的错误VS平台中文乱码 QT的优点关于.pro文件QtCreator快捷键最简单的qt程序按钮的创建对象模型**Qt窗口坐标**体系信号和槽机制connect函数系统自带的信号和槽案例#xff1a;实现点击按钮-关闭窗口的案例 自定义信号和槽案例… 文章目录 一些常见的bug字符集不对产生的错误VS平台中文乱码 QT的优点关于.pro文件QtCreator快捷键最简单的qt程序按钮的创建对象模型**Qt窗口坐标**体系信号和槽机制connect函数系统自带的信号和槽案例实现点击按钮-关闭窗口的案例 自定义信号和槽案例下课-老师触发饿了信号-学生响应信号请吃饭案例使用lambda表达式实现点击按钮关闭窗口功能 信号槽的扩展QT4版本的信号槽写法 总结 一些常见的bug
字符集不对产生的错误 该bug的产生原因字符集不对的原因
解决办法记事本打开该文件 另存为 编码改为带有BOM 的 UTF-8 更改该文件的编码格式 VS平台中文乱码
乱码原因QT使用的utf-8编码进行字符串处理VS使用的是GB2312 二者编码格式不匹配所以中文就会乱码
解决办法1在字符串加上u8
QWidget w;
w.setWindowTitle(u8windows 芒果);
w.show();解决办法2按照上面字符集不对产生的错误解决之后 项目命令行增加一个选项 /utf-8 解决办法3安装拓展 作用自动将文件编码格式保存为utf-8。而如果改为编写C语言文件的时候需要禁用该拓展 方法4在头文件当中增加
#pragma execution_character_set(utf-8)QT的优点
跨平台几乎支持所有的平台接口简单容易上手学习QT框架对学习其他框架有参考意义。一定程度上简化了内存回收机制开发效率高能够快速的构建应用程序有很好的社区氛围市场份额在缓慢上升可以进行嵌入式开发 关于.pro文件
.pro就是工程文件(project)它是qmake自动生成的用于生产makefile的配置文件
QT core gui Qt包含的模块greaterThan(QT_MAJOR_VERSION, 4): QT widgets //大于4版本以上 包含 widget模块TARGET 01_FirstProject //目标 生成的.exe程序的名称
TEMPLATE app //模板 应用程序模板 Application SOURCES main.cpp\ //源文件mywidget.cppHEADERS mywidget.h //头文件 解释 【1】.注释从“#”开始到这一行结束
【2】.模板变量告诉qmake为这个应用程序生成哪种makefile。下面是可供使用的选择TEMPLATE app
app -建立一个应用程序的makefile这是默认值所以如果模板没有被指定这个将被使用lib - 建立一个库的makefilevcapp - 建立一个应用程序的VisualStudio项目文件vclib - 建立一个库的VisualStudio项目文件subdirs -这是一个特殊的模板它可以创建一个能够进入特定目录并且为一个项目文件生成makefile并且为它调用make的makefile
【3】.指定生成的应用程序名TARGET QtDemo
【4】.工程中包含的头文件HEADERS include/painter.h
【5】.工程中包含的.ui设计文件FORMS forms/painter.ui
【6】.工程中包含的源文件SOURCES sources/main.cpp sources
【7】.工程中包含的资源文件RESOURCES qrc/painter.qrc
【8】.greaterThan(QT_MAJOR_VERSION, 4): QT widgets
这条语句的含义是如果QT_MAJOR_VERSION大于4也就是当前使用的Qt5及更高版本需要增加widgets模块。如果项目仅需支持Qt5也可以直接添加“QT widgets”一句。不过为了保持代码兼容最好还是按照QtCreator生成的语句编写 QtCreator快捷键
注释 ctrl /
运行 ctrl r
编译 ctrl b
字体缩放 ctrl 鼠标滚轮
查找 ctrl f
整行移动 ctrl shift ↑ 或者↓
帮助文档 F1
自动对齐 ctrl i;
同名之间的.h 和 .cpp切换 F4
帮助文档 第一种方式 F1 第二种 左侧按钮 第三种QT安装路径下的bin目录例如 C:\Qt\Qt5.6.0\5.6\mingw49_32\bin最简单的qt程序 main函数入口 //main程序入口 argc命令行变量的数量 argv命令行变量的数组
int main(int argc, char *argv[])
{//a应用程序对象在Qt中应用程序对象 有且仅有一个QApplication a(argc, argv);Widget w; //窗口对象w.show();//窗口对象 默认不会显示必须要调用show方法显示窗口//让应用程序对象进入消息循环 让代码阻塞到这行return a.exec();
}QApplication应用程序类是Qt的整个后台管理的命脉它包含主事件循环在其中来自窗口系统和其它资源的所有事件处理和调度。它也处理应用程序的初始化和结束并且提供对话管理
对于任何一个使用Qt的图形用户界面应用程序都只能存在一个QApplication 对象而不论这个应用程序在同一时间内是不是有0、1、2或更多个窗口 a . e x e c ( ) a.exec() a.exec()程序进入消息循环等待对用户输入进行响应。这里main()把控制权转交给QtQt完成事件处理工作当应用程序退出的时候exec()的值就会返回。在exec()中Qt接受并处理用户和系统的事件并且把它们传递给适当的窗口部件。 按钮的创建
在Qt程序中最常用的控件之一就是按钮一个按钮其实就是一个QPushButton类对象其中有两种创建方式
如果只是创建出对象是无法显示到窗口中的所以我们需要依赖一个父窗口也就是指定一个父亲利用setParent函数即可如果想设置按钮上显示的文字利用setText移动按钮位置用move
#include QPushButton
//创建方式1
QPushButton * btn new QPushButton;
btn-setParent(this);//设置父亲 让btn对象依赖在当前Widget窗口中
btn-setText(德玛西亚);//设置文字
btn-move(100,100);//移动位置//创建方式2
QPushButton * btn2 new QPushButton(孙悟空,this);
//下述的this都可以省略
this-resize(600,400);//重新指定窗口大小
this-setWindowTitle(第一个项目);//设置窗口标题
this-setFixedSize(600,400);//限制窗口大小 不可以拖拽去扩大/缩小大小
//重置窗口大小
resize(600,400); //this-resize(...)对于窗口而言我们可以修改左上角窗口的标题setWindowTitle重新指定窗口大小resize或者设置固定的窗口大小setFixedSize 注意如果是在Widget的构造函数当中
QPushButton btnStack;
btnStack.setParent(this);此时该按钮并不会显示在窗口当中因为该对象是在栈上创建的一旦Widget的构造函数执行完成之后该对象就会被销毁因此它不会显示在窗口中。要使 btnStack 对象显示在窗口中你应该将它的生命周期延长使其在窗口的整个生命周期内都存在 可以选择 将btnStack声明为类的成员变量 对象模型 在Qt中创建对象的时候需要提供一个Parent对象指针因为QObject是以对象树的形式组织起来的当你创建一个对象时会看到该对象的构造函数接收一个QObject指针作为参数这个参数就是 parent也就是父对象指针。 【1】.在创建对象时可以提供一个其父对象我们创建的这个QObject对象会自动添加到其父对象的children()列表当父对象析构的时候这个列表中的所有对象也会被析构。注意这里的父对象并不是继承意义上的父类
【2】.QWidget继承自QObject因此也继承了这种对象树关系。一个孩子自动地成为父组件的一个子组件
例如当用户关闭一个对话框的时候应用程序将其删除那么我们希望属于这个对话框的按钮、图标等应该一起被删除。事实就是如此因为这些都是对话框的子组件
【3】.我们也可以自己删除子对象它们会自动从其父对象列表中删除
当我们删除了一个工具栏时其所在的主窗口会自动将该工具栏从其子对象列表中删除并且自动调整屏幕显示
Qt 引入对象树的概念在一定程度上解决了内存问题
当一个QObject对象在堆上创建的时候Qt 会同时为其创建一个对象树。不过对象树中对象的顺序是没有定义的。这意味着销毁这些对象的顺序也是未定义的 任何对象树中的 QObject对象 delete 的时候如果这个对象有 parent则自动将其从 parent 的children()列表中删除如果有孩子则自动 delete 每一个孩子Qt 保证没有QObject会被 delete 两次这是由析构顺序决定的 如果QObject在栈上创建Qt 保持同样的行为
{QWidget window;QPushButton quit(Quit, window);
}作为父组件的 window 和作为子组件的 quit 都是QObject的子类此时这段代码是正确的quit 的析构函数不会被调用两次因为标准 C要求局部对象的析构顺序应该按照其创建顺序的相反过程这段代码在超出作用域时会先调用 quit 的析构函数将其从父对象 window 的子对象列表中删除然后才会再调用 window 的析构函数 错误代码 {QPushButton quit(Quit);QWidget window;quit.setParent(window);
}此时1.父对象的 window 会首先被析构因为它是最后一个创建的对象。在析构过程中它会调用子对象列表中每一个对象的析构函数也就是说 quit 此时就被析构了
2.在 window 析构之后quit 也会被析构因为 quit 也是一个局部变量在超出作用域的时候当然也需要析构。但是这时候已经是第二次调用 quit 的析构函数了C 不允许调用两次析构函数因此程序崩溃了
结论尽量在构造的时候就指定 parent 对象并且大胆在堆上创建。当创建的对象在堆区时候如果指定的父亲是QObject类或者父类是QObject子类派生下来的类可以不用管理释放的操作将对象会放入到对象树中一定程度上简化了内存回收机制 Qt窗口坐标体系
以左上角为原点0,0x以右为正方向y以下为正方向 如果是对于嵌套窗口其坐标是相对于父窗口来说的 信号和槽机制
信号槽实际就是观察者模式。当某个事件发生之后比如按钮检测到自己被点击了一下它就会发出一个信号signal但是这种发出是没有目的的类似广播。如果有对象对这个信号感兴趣它就会使用连接connect函数将想要处理的信号和自己的一个函数称为槽slot绑定来处理这个信号。也就是说当信号发出时被连接的槽函数会自动被回调。 connect函数
connect(sender, signal, receiver, slot);sender发出信号的对象signal发送对象发出的信号 可调用对象receiver接收信号的对象slot接收对象在接收到信号之后所需要调用的函数槽函数 可调用对象
信号槽的优点松散耦合信号的发送端和接收端本身没有任何关联二者通过connect函数进行关联将两端耦合在一起 系统自带的信号和槽
在帮助文档中输入QPushButton首先我们可以在Contents中寻找关键字 signals但是我们发现并没有找到这时候我们应该想到也许这个信号的被父类继承下来的因此我们去他的父类QAbstractButton中就可以找到该关键字 点击signals索引到系统自带的信号有如下几个 槽函数的寻找方式和信号一样只不过他的关键字是slot 案例实现点击按钮-关闭窗口的案例
testQt::testQt(QWidget* parent): QWidget(parent)
{ui.setupUi(this);QPushButton* btn new QPushButton(u8关闭窗口, this);btn-move(100, 200);resize(500, 500);//参数1 信号的发送者 参数2 发送的信号函数的地址 参数3 信号的接受者 参数4 处理的槽函数connect(btn, QPushButton::clicked, this, QWidget::close);
}自定义信号和槽
案例下课-老师触发饿了信号-学生响应信号请吃饭 testQt.cpp testQt::testQt(QWidget* parent): QWidget(parent)
{ui.setupUi(this);//1.创建老师和学生对象this-teacher new Teacher(this);this-stu new Student(this);//点击按钮触发下课QPushButton* btn new QPushButton(u8下课, this);btn-move(200, 200);btn-resize(100, 100);//2.0无参 信号和槽函数连接 假设没有重载版本时的调用情况只有treat()和hungry()/*connect(teacher, SIGNAL(hungry()), stu, SLOT(treat())); //QT4写法connect(teacher, Teacher::hungry, stu, Student::treat); *///2.1无参 信号和槽函数连接 有重载版本时的调用情况/*void(Teacher:: * teacherSignal)() Teacher::hungry;void(Student:: * studentSlot)() Student::treat;connect(teacher, teacherSignal, stu, studentSlot);connect(btn, QPushButton::clicked, teacher, teacherSignal); //信号可以连接信号 当点击事件发生触发teacherSignal信号触发studentSlot槽函数*///2.2有参 信号和槽函数连接 有重载版本时的调用情况/*void(Teacher:: * teacherSignal)(QString) Teacher::hungry;void(Student:: * studentSlot)(QString) Student::treat;connect(teacher, teacherSignal, stu, studentSlot);//connect(btn, QPushButton::clicked, teacher, teacherSignal); //err,原因:信号和槽的参数类型不匹配//clicked的第一个参数为bool teacherSignal函数的参数为QString,信号和槽函数的参数 必须类型一一对应*///3.调用下课函数ClassOver();
}void testQt::ClassOver()
{//emit teacher-hungry();//触发老师饿了信号 -无参版本emit teacher-hungry(u8宫保鸡丁); //触发老师饿了信号 -带参版本
}案例使用lambda表达式实现点击按钮关闭窗口功能 QPushButton* btn new QPushButton(u8close Widget, this);btn-move(200, 200);btn-resize(100, 100);connect(btn, QPushButton::clicked,[]() {qDebug() u8关闭窗口;close(); //this-close(); 关闭窗口
});注意如果第三个参数是this第四个参数是lambda表达式那么第三个参数可以省略 注意
【1】.如果有两个重名的自定义信号和自定义的槽直接连接会报错所以需要利用函数指针来明确指向函数地址 然后再做连接
connect(teacher,Teacher::hungury,student,Student::treat); //void hungury()和void treat()连接//自定义的信号 hungry带参数需要提供重载的自定义信号和 自定义槽
//void hungury(QString name); 自定义信号
//void treat(QString name ); 自定义槽
void (Teacher:: *teacherSingal)(QString) Teacher::hungury;
void (Student:: * studentSlot)(QString) Student::treat;
connect(teacher,teacherSingal,student,studentSlot);补充关于函数指针指向的是类当中的成员函数 class A
{
public:void func(){cout A::func() endl;}
};
void (A::*PFunc)() A::func;
int main()
{A obj;(obj.*PFunc)();//成员函数需要一个对象实例来调用/*obj这是一个已经创建的类A的对象实例。成员函数需要一个对象实例来操作类的数据成员和执行操作。.*这是成员函数指针运算符。它用于将成员函数指针与对象实例关联在一起以便调用成员函数。PFunc这是一个指向成员函数的指针它保存了要调用的成员函数的地址。在这种情况下它指向类A的func()成员函数。()这是函数调用运算符用于调用函数。在这里我们使用它来调用与对象实例obj关联的成员函数PFunc指向的成员函数。*/return 0;
}【2】发送者和接收者都需要是QObject的子类
例外槽函数是全局函数、Lambda 表达式等无需接收者
【3】信号和槽函数返回值是 void信号只需要声明不需要实现槽函数需要声明也需要实现。信号和槽函数都可以进行重载
自定义信号写到$signals$当中自定义槽函数写到public slot当中或者public函数或者全局函数
【4】槽函数是普通的成员函数作为成员函数会受到 public、private、protected 的影响
【5】使用 emit 在恰当的位置发送信号使用connect()函数连接信号和槽
【6】任何成员函数、static 函数、全局函数和 Lambda 表达式都可以作为槽函数
【7】信号槽要求信号和槽的参数一致所谓一致是参数类型一致。如果信号和槽的参数不一致允许的情况是槽函数的参数可以比信号的少但是此时槽函数存在的那些参数的顺序也必须和信号的前面几个一致因为你可以在槽函数中选择忽略信号传来的数据也就是槽函数的参数比信号的少) 信号槽的扩展
【1】一个信号可以和多个槽相连
如果是这种情况这些槽会一个接一个的被调用但是它们的调用顺序不确定
【2】多个信号可以连接到一个槽只要任意一个信号发出这个槽就会被调用
【3】一个信号可以连接到另外的一个信号
当第一个信号发出时第二个信号被发出。除此之外这种信号-信号的形式和信号-槽的形式没有什么区别
【4】信号槽可以被取消链接可以disconnect断开
这种情况并不经常出现因为当一个对象delete之后Qt自动取消所有连接到这个对象上面的槽
disconnect(teacher,teacherSignal2,stu,studentSlot2); //断开信号 和 信号连接的格式一致【5】l 使用Lambda 表达式
在使用QT5 的时候能够支持QT5的编译器都是支持 Lambda 表达式的。在连接信号和槽的时候槽函数可以使用Lambda表达式的方式进行处理 QT4版本的信号槽写法
connect(teacher,teacherSingal,student,studentSlot); //QT5 teacherSingal和studentSlot是函数指针
connect(teacher,SIGNAL(hungry(QString)),student,SLOT(treat(QString))); //QT4版本的写法//connect( 信号的发送者,发送的信号SIGNAL(信号),信号接受者,槽函数SLOT(槽函数))优点参数直观
缺点编译器不会检测参数类型
使用了SIGNAL和SLOT这两个宏作用是将两个函数名转换成了字符串一旦出现连接不成功的情况Qt4是没有编译错误的而是在运行时给出错误。这无疑会增加程序的不稳定性 总结