Migrating from MFC to Qt: Modal window in MFC
-
Hello everybody,
I have a MFC application which I would like to migrate to MFC. However, in the meantime, both need to work together (MFC main app with Qt). If I understand correctly, there is no need of qtwinmigrate as now we can use the Qt into MFC app. In other words, I can do:
int argc = 0; auto qtapp = new QApplication(argc, nullptr); auto widget = new QWidget; widget->show();
I can call qt code from MFC app. However, when a need a modal window I cannot do it. Is there any way to accomplish that? I see this project QtMFCIntegration in which they use something called " transparent shield" MFC which calls the Qtwidget. I'm not really sure if I need to do something like that.
I tried to get the HWND, and set this parent using the QWidget::find. However, I was not able to accomplish the modal window. I was not sure if this was the correct way.
Example:
class MyQtDialog : public QDialog { Q_OBJECT public: explicit MyQtDialog(QWidget* parent = nullptr) : QDialog(parent) { setWindowTitle("Qt Modal Dialog"); QVBoxLayout* layout = new QVBoxLayout(this); QPushButton* button = new QPushButton("Close", this); connect(button, &QPushButton::clicked, this, &QDialog::accept); layout->addWidget(button); setLayout(layout); } }; __declspec(dllexport) void my_about_call(HWND parent) { int argc = 0; QApplication a(argc, nullptr); WId qtWIdParent = reinterpret_cast<WId>(parent); QWidget *qtParent = QWidget::find(qtWIdParent); // Show the Qt modal dialog MyQtDialog qtDialog(qtParent); qtDialog.setWindowModality(Qt::ApplicationModal); qtDialog.exec(); } some_mfc_code() { my_about_call(this->m_pMainWnd->GetSafeHwnd()); }
I addition:
It is true that I basically add this as DLL because if I mix mfc and qt headers I got this error:
static_assert failed: 'On MSVC you must pass the /permissive- option to the compiler.'
If I use this permissive option. I got a lot of errors from mfc headers.
btw, I'm using Qt6.8.1.
Thanks in advance
-
@reymor
I don't know about your whole solution. But I notice that you create a newQApplication
for each call (show a widget, show a dialog). Are you sure this is the best way? Normally you create a Qt application object once and it persists through out your application lifetime. Looks odd to me (might be just me?) to be creating and destroyingQApplication
afresh each time. -
@jsulm said in Migrating from MFC to Qt: Modal window in MFC:
You are not starting Qt event loop (a.exec()). Without it Qt stuff will not work.
In this case, MFC is already running the event loop, so Qt simply uses that.
@reymor said in Migrating from MFC to Qt: Modal window in MFC:
I see this project QtMFCIntegration in which they use something called " transparent shield" MFC which calls the Qtwidget. I'm not really sure if I need to do something like that.
Try it. Does it work?
(I have briefly added QWidget-based windows to an existing MFC app, but I have not tried to use modal dialogs in a hybrid Qt-MFC app)
-
@jsulm said in Migrating from MFC to Qt: Modal window in MFC:
@JKSH OK, didn't know Qt would use the event loop from MFC automatically.
I didn't know either, until I tried to port QtWinMigrate to Qt 6.
Volker (our Chief Maintainer) said:
Based on what I'm seeing in Qt 6's (and Qt 5's) Win32 event dispatcher, QtWinMigrate isn't needed at all, at least not for hooking a Qt UI into a Win32 event loop. The code touched by https://codereview.qt-project.org/c/qt/qtbase/+/387409 is designed to make delivery of posted QEvents work even if Qt is not running the event loop.