Qt绘图与信号事件

2023-11-08

Qt应用开发的基本模式(面向对象)

  1. 继承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;
}
  1. 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;
}
  1. main.cpp
#include "gkapp.h"
// #include "gkdialog.h"

int  main(int argc, char **argv){
    // 创建Qt应用
    GKApp app(argc, argv);
    // 创建对话框
    // 消息循环
    // 返回状态码
    return app.exec();
}
  1. 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)

代码实现

  1. 定义成员

  2. 创建对象

  3. 设置属性

工具实现

  • Qt Designer(Qt设计大师)
  1. 步骤1:创建模板,保存为ui文件

  2. 拖组件满足功能

  3. 外观的设计

  4. 命名规范

  5. 交互设计

    1. 设计槽(slot)函数
    2. 组件的信号与槽函数关联

使用UI

  • 条件是*.ui文件
  1. 编译ui文件为.h文件

    • uic [options] [uifile]
      1. -o 输出的文件 : 建议文件输出为.h文件
  2. 创建ui对象

  3. 使用ui对象的setupUi绑定我们的对话框
    ui->setupUi(this);

  4. 实现ui设计中的槽函数

  5. 所有定义了槽函数的头文件需要编译成moc的cpp文件。

    • cpp需要编译与链接

    • 注意事项;定义槽函数或者是信号的类,需要添加一个宏,Q_OBJECT

    • moc [options] [header-file]

      • 选项: -o 输出的文件moc_***.cpp

Qt画图

  1. Qt应用
    QApplication

    • QDialog
  2. 绘制事件

    • 完成绘图编程模式

    • QPainter

  3. 键盘事件

    • 通过键盘控制=图形的活动
  4. 代码

  • 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多线程

  1. 使用线程完成数据同步处理
  • 代码

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);
}
  1. 通信机制:信号与槽

    1. 定义信号
      在fish.h文件的类中定义:
      •    signals:
           void sign_open();
        
    2. 发送信号
      在fish.cpp文件的run()函数中发送:
      •    emit sign_open();
        
    3. 绑定信号到目标
    4. 目标需要有一个slot函数处理信息
      在dialog.cpp文件中,线程启动前绑定:
      •   QObject::connect(fish, SIGNAL(sign_open()), this, SLOT(repaint()));
          QObject::connect(fish2, SIGNAL(sign_open()), this, SLOT(repaint()));
        
  2. 绘制刷新实现动画

  3. 运行展示
    在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt绘图与信号事件 的相关文章

随机推荐

  • 常见JVM面试题及答案整理

    前言 总结了JVM一些经典面试题 分享出我自己的解题思路 希望对大家有帮助 有哪里你觉得不正确的话 欢迎指出 后续有空会更新 1 什么情况下会发生栈内存溢出 思路 描述栈定义 再描述为什么会溢出 再说明一下相关配置参数 OK的话可以给面试官
  • 实现一个可左右滑动操作的vue3组件

    为了实现左右滑动能够切换页面 便有了做成组件的想法 代码实现 监听touchstart 记录开始位置 监听touchmove 记录移动的位置 计算移动的方向 再把值设置给translateX 计算结果的值要能够跟随手指移动 加入锁定方向 是
  • Oracle 自定义分隔函数

    今天上班时 产品经理反馈客户有一批存量数据中 biz type 存在多个业务键号使用逗号分隔 现在需要将该字段调整为基于逗号分隔的多行记录 Oracle 自定义分隔函数 create or replace function split st
  • 0007.整数反转(简单)

    代码 java版 public class Solution 反转 public static int reverse int x int aa int Math pow 2 31 1 2147483646 int bb int Math
  • Srping:bean循环依赖问题

    Spring 为了解决单例的循环依赖问题 使用了 三级缓存 递归调用时发现 Bean 还在创建中即为循环依赖 单例模式的 Bean 保存在如下的数据结构中 一级缓存 用于存放完全初始化好的 bean private final Map
  • 【Python爬虫与数据分析】爬虫代理IP与访问控制

    目录 一 代理IP 二 正则表达式re 三 通过代理IP对网站循环访问 四 通过selenium工具实现访问控制 注 文末有干货 不过不认真看完你可学不懂 偷笑 一 代理IP 在爬虫对服务器做资源请求时 通常情况是不需要用到代理IP的 但是
  • DBC文件的编辑方法

    1 启动candb 程序 File gt createdatabase选择模板 然后保存dbc文件 2 添加网络节点 在OverallView界面 右击Network nodes选择New弹出如下界面 设置节点名称 把前面编辑好的Messa
  • 一键提升多媒体内容质量:漫谈图像超分辨率技术

    看的一篇图像超分辨推文 在这里记录一下 方便后续查阅 作为将模糊的图像变清晰的神奇技术 图像超分辨率技术在游戏 电影 相机 医疗影像等多个领域都有广泛的应用 在这篇文章中 微软亚洲研究院的研究员们为你总结了图像超分辨率问题中的主流方法 现存
  • html原生js进度条圆形,原生JS环形进度条

    var bg document getElementById canvas1 var ctx bg getContext 2d ctx beginPath ctx lineWidth 10 ctx strokeStyle e5e5e5 va
  • jquery checkbox 设置选中和不选中

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 设置选中 hasApply prop checked true 设置不选中 hasApply prop checked false 获取选中的状态 var status h
  • Active Directory的基本概念

    前言 本文是面对准备加入Active Directory编程的初学者的一份文章 主要是讲解Active Directory 活动目录 的一些概念和相关知识 这篇文章本来是不想写下来的 因为概念性内容的编写需要查阅很多的资料 也怕自己讲的不够
  • 计算机无法识别华为m3,华为M3平板怎么开启学生模式过滤不良网站?

    对于孩子使用电子设备这件事儿 家长们总会陷入到一种矛盾中 即 支持用吧 但是现如今信息复杂 孩子没有自控力 不能每天都盯着 监督不慎误入歧途怎么办 支持不用吧 但是上面又有很多资料资源 值得孩子们去学习 视频教学 益智科普类的软件层出不穷
  • layout_weight 标签用于在线性布局中指定父控件的剩余空间比例的分配

    layout weight 用于在线性布局中指定父控件的剩余空间比例的分配
  • 数学建模竞赛论文中的Word使用

    1 使用样式 除了Word原先所提供的标题 正文等样式外 还可以自定义样式 如果你发现自己是用选中文字然后用格式栏来设定格式的 一定要注意 想想其他地方是否需要相同的格式 如果是的话 最好就定义一个样式 对于相同排版表现的内容一定要坚持使用
  • 如何配置Vue脚手架(Vue CLI)

    第一步 用cmd打开命令提示符 输入命令行 npm config set registry https registry npm taobao org 第二步 打开cmd 输入命令行 npm install g vue cli 中途可能会出
  • MATLAB/simulink时域分析之性能指标(0基础)

    目录 6 时域分析 6 1 性能指标 6 1 1 典型输入信号 6 1 2 一阶系统时域响应 6 1 3 二阶系统时域响应 6 1 4 二阶系统的改善 6 时域分析 由于多数控制系统是以时间作为独立变量 所以人们往往关心输出对时间的响应 对
  • 刷脸支付创新高效促进消费者重新光临

    刷脸支付成为了移动金融产业新的焦点 这离不开代理的卖力推广 刷脸支付代理成为大多创业者的选择 从今往后 脸就是钱包走人寻常百姓家 再也不用担心发生突发情况 尴尬放回商品的局面 现在可以在便利店 部分夫妻店看见这样的画面 收银台不见了 换成了
  • python源码保护之cython

    转载请注明出处 准备 项目需要 是在windows7上操作 python3 7 针对python项目 而非单个的python程序 思路 先将py代码转成c代码 然后编译成pyd window上是pyd linux上是so 文件 安装cyth
  • base64转图片

    base64转图片 param base64Code base64码 public static void convertBase64ToImage String base64Code BufferedImage image byte im
  • Qt绘图与信号事件

    Qt应用开发的基本模式 面向对象 继承QDailog gkdialog h ifndef GK DIALOG H define GK DIALOG H include