目录
创建新的项目
下一步
下一步
下一步
下一步
第一个hell0程序,qt的项目结构
创建顶目的时候 Qwidget、OMainWindow、ODialog 是所有能看到的窗口或者控件的父类,OMainWindow、ODialog 都继承自它
main函数
QApplication 就是EQT里边每个应用程序有且仅有一个的应用程序对象
QApplication:: exec()程序的生命循环、消息循还,当作以下形式
while(1)
{
if(点击x按钮)
break;
if(点击了最小化按钮)
最小化动作;
}
Widget头文件:
Q_OBJECT //宏,引入qt信号和槽的一个宏
HelloWidget(OWidget *parent=0);
//parent窗日指针,父窗口对象的指针
//如果parent为0或者NULL,表示当前窗口对象是个顶层窗口
//顶层窗口就是在任务栏可以找到的窗口
·pro文件
QT | += core gui #引入gt的模块
greaterThan(QT_MAJOR_VERSION,4):QT += widgets 如果qt版本号大于4,则添加widgets
模块到项目中。
指定目标,生成可执行程序的名字 TARGET 01_hello
模板,生成什么文件,app表示应用程序exe,lib就是生成库TEMPLATE = app
命名规范
-
类命名:
- 类名使用驼峰式命名法(CamelCase),首字母大写,例如:
QApplication
。 - Qt类名通常以
Q
开头,以示它们属于Qt框架。
- 类名使用驼峰式命名法(CamelCase),首字母大写,例如:
-
变量命名:
- 变量名使用驼峰式命名法,首字母小写,例如:
myVariable
。
- 变量名使用驼峰式命名法,首字母小写,例如:
-
函数命名文件命名:
- 函数名使用驼峰式命名法,首字母小写,例如:
void myFunction()
。 - 头文件通常使用
.h
扩展名,源文件使用.cpp
扩展名。 - 文件名应该与类名或功能相关联,使用驼峰式命名法,例如:
MyClass.h
、MyClass.cpp
。
- 函数名使用驼峰式命名法,首字母小写,例如:
QtCreator 常用快捷键
运行 ctr +R
编译 ctr +B
帮助文档 F1,点击F1两次跳到帮助界面
跳到符号定义F2 或者 ctr+ 鼠标点击。
注释 ctr+/
字体缩放 ctr+ 鼠标滚轮
整行移动代码ctr+shit+个或↓
自动对齐 ctrl+i
同名之间的.h和.cpp 文件跳转 F4
Qt里边绝大部分的类都是继承自QObject是一个顶层类
父子关系
默认情况下按钮没有认干爹的情况下,是个顶层窗口想要按钮显示在窗口上,就要跟窗口构造父子关系
l setParent
#include "hellowidget.h"
#include "qpushbutton.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
helloWidget w;
QPushButton btn;
btn.setText("按钮");
btn.setParent(&w);
w.show();
return a.exec();
}
2 构造函数传参
#include "hellowidget.h"
#include "qpushbutton.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
helloWidget w;
QPushButton btn("按钮",&w);
w.show();
return a.exec();
}
Qt坐标系
是以父窗口的左上角为0,0
以向右的方向为x的正方向
以向下的方向为y的正方向
顶层窗口就是以屏幕左上角为0,0
btn.move(100,100);
QT常用API函数
move 移动窗口到父窗口某个坐标
resize 重新设置窗口的大小
setFixedsize 设置窗口的固定大小
setWindowTitle 设置窗口标题
setGeometry 同时设置窗口位置和大小,相当于move和resize的结合体
#include "hellowidget.h"
#include "qpushbutton.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
helloWidget w;
QPushButton btn("按钮",&w);
btn.move(100,100);
btn.resize(100,100);
w.setWindowTitle("你好");
w.setFixedSize(400,400);
w.show();
return a.exec();
}
对象树
概念:各个窗口对象通过建立父子关系构造对的一个关系树
内存管理:
父对象释放的时候会自动释放各个子对象(使用children列表)
以后基本都是用new的方式来创建窗口对象
helloWidget::helloWidget(QWidget *parent)
: QWidget(parent)
{
QPushButton *btn = new QPushButton("按钮",this);
}
注意点:
1 父对象能够被释放
2 父对象、子对象,直接或者间接继承自Q0bject
信号和槽机制
信号:各种事件。
槽: 响应信号的动作。
信号发送者
信号
信号接收者
槽:信号的处理动作
connect(信号发送者,信号,信号接收者,槽:信号的处理动作)
QPushButton *btn = new QPushButton("按钮",this);
connect(btn,&QPushButton::clicked,this,&helloWidget::close);
自定义信号和槽
自定义信号
函数声明在类头文件的signals域下面
void 类型的函数,没有返回值
可以有参数,也可以重裁
只有声明,没有实现定义
触发信号 emit obj->sign(参数...)
自定义槽
函数声明在类头文件的public/private/protected slots域下面(qt4以前的版本)qt5 就可以声明在类的任何位置,还可以是静态成员函数、全局函数、lambda表达式
void 类型的函数,没有返回值
可以有参数,也可以重载
不仅有声明,还得有实现
参数二义性问题
使用函数指针赋值,让编译器自动挑选符合类型的函数
#include <iostream>
void foo(int x) {
std::cout << "foo(int): " << x << std::endl;
}
void foo(double x) {
std::cout << "foo(double): " << x << std::endl;
}
int main() {
void (*funcPtr)(int) = foo; // 函数指针类型为 void (*)(int)
funcPtr(10); // 编译器会选择匹配的 foo(int)
funcPtr = foo; // 此时编译器可以自动选择 foo(int) 或者 foo(double) 中的一个
funcPtr(3.14); // 编译器会选择匹配的 foo(double)
return 0;
}
使用static_cast 强制转换 ,让编译器自动挑选符合类型的函数
#include <iostream>
void foo(int x) {
std::cout << "foo(int): " << x << std::endl;
}
void foo(double x) {
std::cout << "foo(double): " << x << std::endl;
}
int main() {
// 使用 static_cast 明确指定函数指针类型
void (*funcPtr)(int) = static_cast<void (*)(int)>(foo);
funcPtr(10); // 编译器会选择匹配的 foo(int)
// 使用 static_cast 明确指定函数指针类型
funcPtr = static_cast<void (*)(int)>(foo);
funcPtr(3.14); // 编译器会选择匹配的 foo(double)
return 0;
}
信号和槽的参数关系
必须同时满足以下两点
信号和槽函数的参数类型必须对应
信号和槽函数的参数个数不需要一致,信号函数参数个数>=槽函数参数个数
hungry(QString) -> treat () OK
hungry(Qstring) -> treat (int) 编译出错
hungry(Qstring,int) -> treat (int) 编译出错
QDebug
qdeubg输出Qstring默认会转义
解决方法两个
将String转成char*
qDebúg()<<"Student treat teacher with "<<what.toUtf8 ().data();
使用qDebug().noquote()
qDebug().noquote()<<"Student treat teacher with "<<what ;