转载: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)inmoc.exe" "%(FullPath)" -o ".GeneratedFilesmoc_%(Filename).cpp"
输出:
.GeneratedFilesmoc_%(FileName).cpp
附加依赖项
$(QTDIR)inmoc.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++常规--》附加包含目录
连接器--》附加库
链接器--》输入--》附加依赖项
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的窗口中