目录
0x00 Qt的组成
- Qt编译器 编译C C++代码 集成了gcc g++
- Qt creator 集成编辑器
- 资源编译器 rcc
- UI编译器 UIC:从.ui文件(xml)中编译生成对应的.h文件和.cpp文件
一个简单的Qt程序
Qt Widgets Application 基于窗口的应用程序
Qt Console Application 控制台应用程序
.pro项目文件,用来规定当前项目的类型、使用什么库、包含的源文件、包含的头文件、搜索目录,一旦.pro文件修改了,就需要重新执行qmake(qmake用来生成makefile文件)
makefile是一个描述性文件,用来描述我要编译那些文件、编译方式是什么
MFC 微软基础类库,包含了大量的基类,程序员编写一个自己的类,继承MFC的类
同样Qt也有大量的库,供开发者直接或者间接的使用
比如,窗口
Dialog 对话框,用于和用户交互
Widget 基础窗口类 ,用于包含一些控件的处理
MainWindow 主窗口,可以附带菜单,标题,状态栏
QApplication 窗口程序的核心
QCoreApplication 窗口
QObject Qt基础类
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT //宏
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
在类中加入一个宏 Q_OBJECT,预编译的时候,该宏就会被替换为下面这一大段。表示这个类支持信号和槽。信号和槽是QT的核心,消息时win32的核心,QT中通过信号和槽完成。
#define Q_OBJECT \
public: \
QT_WARNING_PUSH \
Q_OBJECT_NO_OVERRIDE_WARNING \
static const QMetaObject staticMetaObject; \
virtual const QMetaObject *metaObject() const; \
virtual void *qt_metacast(const char *); \
virtual int qt_metacall(QMetaObject::Call, int, void **); \
QT_TR_FUNCTIONS \
private: \
Q_OBJECT_NO_ATTRIBUTES_WARNING \
Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
QT_WARNING_POP \
struct QPrivateSignal {}; \
QT_ANNOTATE_CLASS(qt_qobject, "")
0x01 第一个QT程序
套路:我们自己定义一个子类去继承QT提供的父类
例如我们定义一个Widget窗口类去继承QT提供QWidget类
然后在main入口函数中将该类实例化为对象,调用show方法,就会生成一个窗口
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget> //将需要继承的父类先include进来
//套路:我们自己定义一个子类去继承QT提供的父类
//例如我们定义一个Widget窗口类去继承QT提供QWidget类
//然后在main入口函数中将该类实例化为对象,调用show方法,就会生成一个窗口
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(); //构造函数
~Widget(); //析构函数
void setui(); //设置窗口的UI布局
};
#endif // WIDGET_H
widget.c
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
//构造函数 调用setui() 初始化窗口布局
Widget::Widget()
{
this->setui();
}
Widget::~Widget()
{
}
//初始化窗口UI,这里我们只给该窗口添加一个可以关闭窗口的按钮
void Widget::setui(){
//this指向实例化生成的窗口对象
//setGetmetry就是设置窗口的位置和大小:左上角(x,y)坐标 宽和高
this->setGeometry(100,100,1000,1000);
//按钮 将按钮放置在窗口中 //文字、父窗口
QPushButton* pPushButton = new QPushButton("关闭窗口",this);
//设置按钮的位置与大小
pPushButton->setGeometry(0,0,100,50);
//只设置按钮的位置
//pPushButton->move(200,200);
//使用信号和槽来 监听处理按钮的点击信号
connect(pPushButton,SIGNAL(clicked(bool)),this,SLOT(close()));
//信号源、什么信号、接收者、如何处理
//pPushButton 发出一个点击信号,由窗口来接收,调用窗口类的槽函数close关闭窗口
}
入口函数 main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w; //实例化我们的窗口类为窗口对象
w.show(); //将窗口显示出来
return a.exec();
}
运行测试:
一些小技巧:
我们在头文件中定义函数原型完毕之后,直接按住alt+回车 就可以在源文件中添加函数的实现
将上面的代码风格规范一下:
头文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPushButton>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(); //构造函数
~Widget(); //析构函数
void Setui(); //设置窗口的UI布局
void Connect(); //专门放信号和槽
private:
QPushButton* pPushButton;
};
#endif // WIDGET_H
源文件:
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
//构造函数 调用setui() 初始化窗口布局
Widget::Widget()
{
this->Setui(); //建立UI 类似于Web开发中 HTML文件建立页面骨架
this->Connect();//定义信号和槽 类似Web开发中专门将js代码提取出来
}
Widget::~Widget()
{
}
//初始化窗口UI,这里我们只给该窗口添加一个可以关闭窗口的按钮
void Widget::Setui(){
this->setGeometry(100,100,1000,1000);
this->pPushButton = new QPushButton("关闭窗口",this);
pPushButton->setGeometry(0,0,100,50);
}
//专门用来放信号和槽,类似于web开发中将js文件专门提了出来
void Widget::Connect()
{
connect(this->pPushButton,SIGNAL(clicked(bool)),this,SLOT(close()));
}
通过ui文件生成的.h 和.cpp 文件中所做的事情和我们上面做的事情基本完全类似
自动生成的ui->setupUi(this) 做的事情其实就是我们之前Setui做的事情
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
按住ctrl可以查看setupUi的源代码:
/********************************************************************************
** Form generated from reading UI file 'mainwindow.ui'
**
** Created by: Qt User Interface Compiler version 5.12.10
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H
#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QListView>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_MainWindow
{
public:
QWidget *centralwidget;
QListView *listView;
QPushButton *pushButton;
QPushButton *pushButton_2;
QMenuBar *menubar;
QStatusBar *statusbar;
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(800, 600);
centralwidget = new QWidget(MainWindow);
centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
listView = new QListView(centralwidget);
listView->setObjectName(QString::fromUtf8("listView"));
listView->setGeometry(QRect(160, 60, 256, 192));
pushButton = new QPushButton(centralwidget);
pushButton->setObjectName(QString::fromUtf8("pushButton"));
pushButton->setGeometry(QRect(30, 150, 80, 24));
pushButton_2 = new QPushButton(centralwidget);
pushButton_2->setObjectName(QString::fromUtf8("pushButton_2"));
pushButton_2->setGeometry(QRect(30, 200, 80, 24));
MainWindow->setCentralWidget(centralwidget);
menubar = new QMenuBar(MainWindow);
menubar->setObjectName(QString::fromUtf8("menubar"));
menubar->setGeometry(QRect(0, 0, 800, 22));
MainWindow->setMenuBar(menubar);
statusbar = new QStatusBar(MainWindow);
statusbar->setObjectName(QString::fromUtf8("statusbar"));
MainWindow->setStatusBar(statusbar);
retranslateUi(MainWindow);
QMetaObject::connectSlotsByName(MainWindow);
} // setupUi
void retranslateUi(QMainWindow *MainWindow)
{
MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", nullptr));
pushButton->setText(QApplication::translate("MainWindow", "PushButton", nullptr));
pushButton_2->setText(QApplication::translate("MainWindow", "PushButton", nullptr));
} // retranslateUi
};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MAINWINDOW_H
ui其实就是一个该类的实例,setupUi将各种组件都挂在了该实例上
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
0x02 QT中比较重要的类
QString QT中封装的字符串类
Qstring str = "hello";
str+= "world" ;
str.append("你好中国");
str.sprintf() //格式化字符串
qDebug类 调试输出
以一个简单的加法器为例:
mainwindow.h头文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
void Connect();
//声明槽函数
public slots:
void Calculate();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->Connect();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::Connect()
{
connect(ui->btn_cal,SIGNAL(clicked()),this,SLOT(Calculate()));
}
void MainWindow::Calculate()
{
QString strnum1 = ui->lineEditNum1->text(); //获取input框的值
QString strnum2 = ui->lineEditNum2->text();
int num1 = strnum1.toInt();
int num2 = strnum2.toInt();
int result = num1 + num2;
QString strResult;
// strResult.sprintf("%d",result);
strResult = QString("%1").arg(result);
ui->lineEditNum3->setText(strResult);
// qDebug() << strnum1;
}
入口函数:
#include "widget.h"
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow main_window;
main_window.show();
return a.exec();
}
效果:
容器:
QT对 STL 标准模板库进行了进一步的封装
QList
QVector
QSet
QMap
QHash
QList<int> intlist;
intlist.append(13);
intlist.append(14);
intlist.append(111);
//迭代器
QListIterator<int> intIterator(intlist);
while(intIterator.hasNext()){
qDebug()<<intIterator.next()