轉載: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++常規--》附加包含目錄
連接器--》附加庫
鏈接器--》輸入--》附加依賴項
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的窗口中