MFC窗口中嵌入QT窗口(一)
转载:https://blog.csdn.net/m0_37837218/article/details/108772975
转载:https://blog.csdn.net/sinat_24206709/article/details/77185974
最近因为项目需要,要在MFC程序中嵌入QT的窗口,就是Qt作为MFC的子窗口嵌入到客户区,查了网上资料,需要用到其中的qmfcapp.h qmfcapp.cpp qwinwidget.h qwinwidget.cpp等文件,下载地址
第一步、新建基于对话框的MFC程序
第二步、把qmfcapp.h qmfcapp.cpp qwinwidget.h qwinwidget.cpp放入到工程目录下,然后导入到工程
第三步、QMfcApp和QWinWidget中含有Q_OBJECT的头文件,要给该文件配置自定义生成工具
1.分别选择qmfcapp.h和qwinwidget的头文件,右键,点击属性
2.在配置属性中选择常规,将项类型修改为“自定义生成工具”
3.点击应用后会出现一个新的节点"自定义生成工具"
4.在命令行输入
"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets"
输出:
.\GeneratedFiles\moc_%(FileName).cpp
附加依赖项
$(QTDIR)\bin\moc.exe
%(FullPath)
$(QTDIR) 是一个环境变量,是安装版本的Qt的目录
四、 生成moc文件
右击qmfcapp.h,选择 “编译”,则在文件夹GeneratedFiles中生成moc_qmfcapp.cpp,文件qwinwidget.h同样的操作
五、新建文件夹筛选器 “GeneratedFiles”,把"moc_qmfcapp.cpp"和"moc_qwinwidget.cpp"导入到工程中
六、编译错误
解决办法:qmfcapp.cpp、qwinwidget.cpp、moc_qmfcapp.cpp、moc_qwinwidget.cpp属性-->C/C++-->预编译头--> 创建/使用预编译头改为“不使用预编译头”。这样编译就通过了。
七、配置Qt按照目录,因为QMfcApp和QWinWidget两个类中引用了Qt的库文件
工程属性--》C/C++常规--》附加包含目录
$(QTDIR)\include $(QTDIR)\include\QtCore $(QTDIR)\include\QtGui $(QTDIR)\include\QtGui\5.9.1\QtGui $(QTDIR)\include\QtWidgets
连接器--》附加库
$(QTDIR)\lib
链接器--》输入--》附加依赖项
Qt5Core.lib
Qt5Gui.lib
Qt5Widgets.lib
根据自己的需要配置,这个基本的需求能满足
八、程序入口初始化Qt
BOOL WindowsApp::InitInstance() { .................. // Qt initialization QMfcApp::instance(this); .................. return true; }
重写 virtual int Run()虚函数
int CQtMfcApp::Run() { int result = QMfcApp::run(this); delete qApp; return result; }
九、在MFC对话框中声明QtWidget的指针成员
class QWinWidget; // CQtMfcDlg 对话框 class CQtMfcDlg : public CDialogEx { // 构造 public: CQtMfcDlg(CWnd* pParent = NULL); // 标准构造函数 // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_QTMFC_DIALOG }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: HICON m_hIcon; // 生成的消息映射函数 virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP() private: QWinWidget * m_pWidget; }
在OnInitDialog函数中动态创建QWidget
BOOL CQtMfcDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // 将“关于...”菜单项添加到系统菜单中。 // IDM_ABOUTBOX 必须在系统命令范围内。 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { BOOL bNameValid; CString strAboutMenu; bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); ASSERT(bNameValid); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 m_pWidget = new QWinWidget(this);
m_pWidget->setStyleSheet("background-color:red;");//Qt窗口背景色 QHBoxLayout *hbox = new QHBoxLayout(m_pWidget); QLabel *label = new QLabel("Enter text:", m_pWidget); QLineEdit *edit = new QLineEdit(m_pWidget); hbox->addWidget(label); hbox->addWidget(edit); m_pWidget->move(0, 0); m_pWidget->setGeometry(0, 0, 100, 100); m_pWidget->show(); return TRUE; // 除非将焦点设置到控件,否则返回 TRUE }
十、在对话框销毁的时候销毁QWingets窗口
void CQtMfcDlg::OnDestroy() { delete m_pWidget; m_pWidget = 0; CDialogEx::OnDestroy(); // TODO: 在此处添加消息处理程序代码 }
运行结果:红色区域就是Qt的窗口,作为子窗口嵌入到MFC的窗口中
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理