文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

MFC程序中使用QT开发界面的实现步骤是什么

2023-06-25 21:46

关注

MFC程序中使用QT开发界面的实现步骤是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

如果你有一个现成的MFC项目在做维护,但是你厌倦了使用MFC繁琐的操作来做界面美化,或者你需要在这个项目中用到QT里面好用的某些功能;亦或者是你需要使用某些只能在MFC中使用的组件,但是界面这部分已经用QT做好了。那么这篇文章可能可以帮助到你

演示环境使用Visual Studio 2019 + QT5.12.8 版本

添加QT依赖

首先创建一个基于对话框的MFC工程,当然其他的像是多文档、单文档工程也是可以的,只是为了简单起见我这里用的是对话框
然后通过鼠标右键点击项目,然后依次点击属性 --> C/C++ -->常规在工程的附加头文件中添加上QCore、QGui、QWidget和QT的头文件路径

MFC程序中使用QT开发界面的实现步骤是什么

MFC程序中使用QT开发界面的实现步骤是什么

这里记得按照对应编译选项来选择包含64位或者32。
接着在连接器–>常规 中的附加库目录中添加qt的lib库

MFC程序中使用QT开发界面的实现步骤是什么

MFC程序中使用QT开发界面的实现步骤是什么

最后再在连接器–>输入中添加依赖的lib文件,需要注意的是,debug版本需要链接上带d的lib文件,release则链接上不带d的。
MFC程序中使用QT开发界面的实现步骤是什么
先编译一下,如果没有问题,qt相关的配置已经完成了

添加信号槽机制

MFC是基于Windows 消息队列来处理和响应ui事件的,而qt是采用信号槽机制来响应的,我们虽然添加了qt的依赖,但是现在只能使用其他的qt库,无法使用qt中的信号槽,需要额外添加一些组件来使mfc支持信号槽。

好在这部分需求qt相关的研发人员已经考虑到了,可以在github中找到 QMfcApp
我们可以将这两个文件给拷贝下来,添加到项目中。并且在cpp文件相应位置添加上 #include "pch.h"包含预处理头

中间会有报错,这是因为在Unicode 字符集下 CString 中的字符串类型是 wchar_t* QString::fromLocal8bit 无法 从 wchar_t* 转化为 char* 所以这里可以修改一下,使用 QString::fromStdWString(),然后进行编译

在QMfcApp.cpp的注释里面可以看到,如何使用它

首先在app类的InitInstance 函数中初始化QApplication类

BOOL CMFCWithQtApp::InitInstance(){CWinApp::InitInstance();QMfcApp::instance(this);return true;}

然后需要重写 app类的run 方法,在该方法中调用QMFC 的run方法

int CMFCWithQtApp::Run(){int result = QMfcApp::run(this);delete qApp;return result;}

再次编译一下,完成了往mfc中添加信号槽机制的功能

添加qt界面

在项目中新建一个界面类,让他继承自QWidget,如下

// MainUI.h#pragma once#include <QWidget>class MainUI: public QWidget{Q_OBJECTpublic:MainUI(QWidget* parent = nullptr);~MainUI();};//MainUI.cpp#include "pch.h"#include "MainUI.h"#include <QPushButton>MainUI::MainUI(QWidget* parent) :QWidget(parent){setWindowTitle("Qt Windows");setFixedSize(800, 720);QPushButton* pBtn = new QPushButton(QString::fromLocal8Bit("这是一个Qt按钮"), this);}MainUI::~MainUI(){}

然后在App 类的 InitInstance 中启动该界面

BOOL CMFCWithQtApp::InitInstance(){CWinApp::InitInstance();QMfcApp::instance(this);MainUI ui;ui.show();QMfcApp::exec();return FALSE;}

然后编译,这个时候发现会在链接的时候包一些错误,找不到一些 meta 的函数的定义

配置元编译过程

传统的c/c++ 从源代码到生成可执行文件的过程需要经过预编译、编译、链接。而qt在预编译前会进行元编译,生成一个moc_开头的源码文件,后续编译的真正的文件其实是这个元编译生成的文件。MFC项目不会经历这一步,所以会报错。

MainUI.h 上点击右键,选择属性, 将项目类型选择为自定义生成工具
MFC程序中使用QT开发界面的实现步骤是什么
然后应用,这个时候会出现新的选项
MFC程序中使用QT开发界面的实现步骤是什么
在命令行和输入这两栏中分别填入 "moc.exe" "%(FullPath)" -o ".\GeneratedFiles\moc_%(Filename).cpp" "-fpch.h" "-f../MainUI.h".\GeneratedFiles\moc_%(Filename).cpp

命令行的含义是会使用moc元编译器编译当前文件,并将生成的文件放入到当前目录下的GeneratedFiles子目录中,并且以moc_开头作为文件名,后面 -f 表示生成的新文件中会包含 #include "pch.h"#include "../MainUI.h"

然后在文件中选择右键,编译。这样将会生成moc文件(两边的双引号也好包含进去)

如果编译的时候报找不到moc.exe 这样的错误,请配置QT中的bin路径到环境变量中

我们将新生成的文件添加到项目中

MFC程序中使用QT开发界面的实现步骤是什么

再次编译,成功过后点击运行就可以看到qt界面已经展示出来了

MFC程序中使用QT开发界面的实现步骤是什么

一些问题的处理

窗口出来了,但是在我的环境下出现两个问题,关闭窗口后进程无法退出;程序退出后出现内存泄露的问题

针对这两个问题可以在QMfcApp.cpp 文件中修改

// 表示在最后一个qt窗口退出时,关闭QApplicationsetQuitOnLastWindowClosed(true); //将之前的false改为true
// ~QMfcApp() 中添加这两句,当析构完成后关闭进程HANDLE hself = GetCurrentProcess();TerminateProcess(hself, 0);

测试信号槽

我们可以在MainUI中添加信号槽

MainUI::MainUI(QWidget* parent) :QWidget(parent){setWindowTitle("Qt Windows");setFixedSize(800, 720);QPushButton* pBtn = new QPushButton(QString::fromLocal8Bit("这是一个Qt按钮"), this);connect(pBtn, &QPushButton::clicked, [=]() {QMessageBox::information(this, QString::fromLocal8Bit("信号槽"), QString::fromLocal8Bit("这是由信号槽弹出来的"));});}

点击按钮之后,消息框也正常弹出来了

MFC程序中使用QT开发界面的实现步骤是什么

使用qt designer 设计界面

使用 qtdesigner 设计这样一个界面

MFC程序中使用QT开发界面的实现步骤是什么
qtdesigner 会生成一个.ui文件,在qt的开发环境中,会自动使用uic.exe 将这个文件生成一个对应的.h文件。我们先将ui文件导入到项目,并且按照之前的步骤设置自定义生成工具,填入如下命令行

"uic.exe" "%(FullPath)" -o ".\ui_%(Filename).h"

并且填写上输出路径.\ui_%(Filename).h

编译之后会生成一个对应的ui_MainUi.h 文件,修改对应的MainUI.h 头文件,加上关于它的引用,并且添加一个ui的对象指针

//MainUI.h#pragma once#include <QWidget>#include "ui_Main.h"class MainUI: public QWidget{Q_OBJECTpublic:MainUI(QWidget* parent = nullptr);~MainUI();private:Ui::mainUI* m_pUI;};

在类的构造中,使用ui对象来产生界面元素

//MainUI.cpp#include "pch.h"#include "MainUI.h"#include <QPushButton>#include <QMessageBox>MainUI::MainUI(QWidget* parent) :QWidget(parent),m_pUI(new Ui::mainUI()){m_pUI->setupUi(this);connect(m_pUI->pushButton, &QPushButton::clicked, [=]() {QMessageBox::information(this, QString::fromLocal8Bit("qt 信号槽测试"), m_pUI->lineEdit->text());});}MainUI::~MainUI(){delete m_pUI;}

执行效果如下

MFC程序中使用QT开发界面的实现步骤是什么

看完上述内容,你们掌握MFC程序中使用QT开发界面的实现步骤是什么的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程网行业资讯频道,感谢各位的阅读!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯