Qt应用开发的基本模式(面向对象)
- 继承QDailog
gkdialog.h
#ifndef GK_DIALOG_H
#define GK_DIALOG_H
#include <QtWidgets/QDialog>class GKDialog: public QDialog{
public:GKDialog(QWidget *parent=0);~GKDialog();
};
#endif
gkdialog.cpp
#include "gkdialog.h"
#include <iostream>GKDialog::GKDialog(QWidget *parent):QDialog(parent){std::cout << "对话框初始化" << std::endl;
}GKDialog::~GKDialog(){std::cout << "释放" << std::endl;
}
- QApplication
gkapp.h
#ifndef GK_APP_H
#define GK_APP_H
#include <QtWidgets/QApplication>
#include "gkdialog.h"
class GKApp : public QApplication{
public:GKApp(int argc, char **argv);~GKApp();
private:GKDialog *dlg;
};
#endif
gkapp.cpp
#include "gkapp.h"
#include <iostream>
GKApp::GKApp(int argc, char **argv):QApplication(argc, argv),dlg(new GKDialog()){ // 构造初始化列表dlg = new GKDialog();dlg->resize(600, 400);dlg->move(200, 200);dlg->show();std::cout << "应用初始化" << std::endl;
}GKApp::~GKApp(){std::cout << "应用释放" << std::endl;delete dlg;
}
- main.cpp
#include "gkapp.h"
// #include "gkdialog.h"int main(int argc, char **argv){// 创建Qt应用GKApp app(argc, argv);// 创建对话框// 消息循环// 返回状态码return app.exec();
}
- Makefile
INCLUDES = /I "C:/Qt/Qt5.13.0/5.13.0/msvc2017_64/include"LIBS = /LIBPATH:"C:/Qt/Qt5.13.0/5.13.0/msvc2017_64/lib" \/DYNAMICBASE \"Qt5Widgets.lib" \"Qt5Gui.lib" \"Qt5Core.lib"
CL_ARGS = /EHsc \/MD \/source-charset:utf-8 \/execution-charset:utf-8 \/nologo
LINK_ARGS = /MACHINE:X64 /NOLOGO main:main.cpp gkapp.cpp gkdialog.cpp@cl /c $(CL_ARGS) /Fo:main.obj $(INCLUDES) main.cpp@cl /c $(CL_ARGS) /Fo:app.obj $(INCLUDES) gkapp.cpp@cl /c $(CL_ARGS) /Fo:dialog.obj $(INCLUDES) gkdialog.cpp@link $(LINK_ARGS) $(LIBS) /OUT:main.exe main.obj app.obj dialog.obj clean:@del *.exe *.obj *.exp 2>/Nul
- 说明:
- 三种使用模式的体会:
- 第一种对话框与应用程序并列呈现,我们通常不采用这种并列的方式
- 第二种(即为上面的代码形式),对话框与应用程序为包含关系,这种方式可控性强、风险低。
- 三种使用模式的体会:
设计UI(Qt Designer)
代码实现
-
定义成员
-
创建对象
-
设置属性
工具实现
- Qt Designer(Qt设计大师)
-
步骤1:创建模板,保存为ui文件
-
拖组件满足功能
-
外观的设计
-
命名规范
-
交互设计
- 设计槽(slot)函数
- 组件的信号与槽函数关联
使用UI
- 条件是*.ui文件
-
编译ui文件为.h文件
uic [options] [uifile]
-o 输出的文件
: 建议文件输出为.h文件
-
创建ui对象
-
使用ui对象的setupUi绑定我们的对话框
ui->setupUi(this); -
实现ui设计中的槽函数
-
所有定义了槽函数的头文件需要编译成moc的cpp文件。
-
cpp需要编译与链接
-
注意事项;定义槽函数或者是信号的类,需要添加一个宏,Q_OBJECT
-
moc [options] [header-file]
- 选项:
-o 输出的文件moc_***.cpp
- 选项:
-
Qt画图
-
Qt应用
QApplication- QDialog
-
绘制事件
-
完成绘图编程模式
-
QPainter
-
-
键盘事件
- 通过键盘控制=图形的活动
-
代码
hwdialog.h
#ifndef HW_DIALOG_H
#define HW_DIALOG_H
#include <QtWidgets/QDialog>
#include <QtGui/QkeyEvent>class HWDialog: public QDialog{
public:HWDialog(QWidget *parent=0);~HWDialog();
public:virtual void paintEvent(QPaintEvent *e);virtual void keyPressEvevt(QKeyEvent *e);
private:int x, y;
};
#endif
hwdialog.cpp
#include "hwdialog.h"
#include <iostream>
#include <QtGui/QPainter>HWDialog::HWDialog(QWidget *parent):QDialog(parent),x(100), y(100){}HWDialog::~HWDialog(){}void HWDialog::paintEvent(QPaintEvent *e){QPainter painter(this);QColor color(255, 0, 0, 255);QPen pen(color);painter.setPen(pen);painter.drawRoundedRect(x, y, 100,200,20, 15);
}void HWDialog::keyPressEvevt(QKeyEvent *e){if(e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Up){y -= 2;}if(e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Down){y += 2;}if(e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Left){x -= 2;}if(e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Right){x += 2;}this->repaint();
}
-
QApplication、main.cpp、Makefile三部分代码与Qt开发的基本模式相同,在此不再进行展示。
-
运行展示
Qt多线程
- 使用线程完成数据同步处理
- 代码
thdialog.h
#ifndef TH_DIALOG_H
#define TH_DIALOG_H
#include <QtWidgets/QDialog>
#include <QtGui/QKeyEvent>
#include "thfish.h"class THDialog: public QDialog{
public:THDialog(QWidget *parent=0);~THDialog();
public:virtual void paintEvent(QPaintEvent *e);virtual void keyPressEvent(QKeyEvent *e);private:THFish *fish;THFish *fish2;
};#endif
thdialog.cpp
#include "thdialog.h"
#include <iostream>
#include <QtGui/QPainter>
THDialog::THDialog(QWidget *parent):QDialog(parent),fish(new THFish(100, 100)),fish2(new THFish(200, 100)){fish->start(); // 线程启动fish2->start();
}THDialog::~THDialog(){}// override绘制函数
void THDialog::paintEvent(QPaintEvent *e){// 在这里完成绘制工作QPainter painter(this);fish->showFish(&painter);fish2->showFish(&painter);
}
void THDialog::keyPressEvent(QKeyEvent *e){if(e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Up){// std::cout << "up" << std::endl;fish->changeDir(90);fish->swim();}if(e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Down){// std::cout << "down" << std::endl;fish->changeDir(270);fish->swim();}if(e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Left){// std::cout << "left" << std::endl;fish->changeDir(180);fish->swim();}if(e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Right){// std::cout << "right" << std::endl;fish->changeDir(0);fish->swim();}this->repaint();
}
thfish.h
#ifndef TH_FISH_H
#define TH_FISH_H
#include <QtCore/QThread>
#include <QtGui/QPainter>class THFish : public QThread{Q_OBJECT
public:THFish(int x=0, int y=0, int m=45, int d=0);void openMouth();void changeDir(int dir);void swim();void showFish(QPainter *painter);
protected:virtual void run();
private:int mouth;int pos_x, pos_y;int dir;bool isopen;
};
#endif
thfish.cpp
#include "thfish.h"THFish::THFish(int x, int y, int m, int d):mouth(m), isopen(false), pos_x(x), pos_y(y), dir(d){}
void THFish::run(){while(true){openMouth();QThread::usleep(100000);}
}
void THFish::openMouth(){if(isopen){mouth += 5;if(mouth >= 45){isopen=!isopen;mouth = 45;}}else{mouth -= 5;if(mouth <= 0){isopen=!isopen;mouth = 0;}}
}
void THFish::changeDir(int dir){this->dir = dir;
}
void THFish::swim(){if(this->dir == 0){pos_x += 2;}if(this->dir == 90){pos_y -= 2;}if(this->dir == 180){pos_x -= 2;}if(this->dir == 270){pos_y += 2;}
}
void THFish::showFish(QPainter *painter){QColor color(255, 0, 0, 255);QPen pen(color);painter->setPen(pen);painter->drawPie(pos_x, pos_y, 50, 50, mouth * 16 + dir * 16, (360 - 2 * mouth) *16);
}
-
通信机制:信号与槽
- 定义信号
在fish.h文件的类中定义:-
signals:void sign_open();
-
- 发送信号
在fish.cpp文件的run()函数中发送:-
emit sign_open();
-
- 绑定信号到目标
- 目标需要有一个slot函数处理信息
在dialog.cpp文件中,线程启动前绑定:-
QObject::connect(fish, SIGNAL(sign_open()), this, SLOT(repaint()));QObject::connect(fish2, SIGNAL(sign_open()), this, SLOT(repaint()));
-
- 定义信号
-
绘制刷新实现动画
-
运行展示