PDA

View Full Version : Using Qt 5, how do I create a user interface (modeless dialog box) in a Qt DLL?



astodolski
3rd December 2013, 19:50
I understand that the QtGUI has changed significantly from Qt4 to Qt5.

I want to create a DLL that has a user interface (GUI).
This DLL must work with third party applications that have their own user interface.
The third party applications can be written in Qt, .NET, MFC, and other programming languages other than C/C++.
I created a DLL that displays a modeless dialog box in Qt 4.8.4 and works as designed.
When I upgraded the DLL for Qt 5.1.1:

The widgets (combo-box, push button, check box) on the dialog box no longer respond to mouse clicks.
The frame is active and the dialog box can be moved around.
The window repaints when obscured/exposed by another window.


The model I am using was provided by the twain consortium and is similar to other sample code I located on this and other forums.


For example, the main entry function in the DLL launches a thread for the QApplication:


// Coerce the QCoreApplication instance if it exists to a QApplication.
QApplication * pApp = qApp;
if (pApp)
{
// Test for consistency between the application QT version and
// the one for the DS.
int nV1App = 0;
int nV2App = 0;
int nV3App = 0;
SSCANF(qVersion(),"%d.%d.%d",&nV1App, &nV2App, &nV3App);
int nV1DS = (BYTE)(QT_VERSION>>16);
int nV2DS = (BYTE)(QT_VERSION>>8);
// int nV3DS = (BYTE)QT_VERSION;
if (nV1App < nV1DS || (nV1App == nV1DS && nV2App < nV2DS))
return TWRC_FAILURE;
}
if (!pApp)
{
#ifdef TWNDS_OS_WIN
_get_pgmptr(&pWinAppName);
m_pUIThread = new UIThread(this, UIInfo);
m_pUIThread->start();
// Wait on the semaphore for the thread to start running
// and that the thread has launched the dialog box.
ScanXGUIEnabledSem.acquire(1);
#endif



The thread (m_pUIThread) creates the QApplication in its run method:



void UIThread::run()
{
// Launch a QApplciation. (Windows only)
// There are no command line arguments.
int argc = 1;
m_pQtApp = new QApplication(argc, &pWinAppName);
if (m_pQtApp)
{
#ifdef TWNDS_OS_WIN
// Create the dlg and make it visible.
m_pDlg = new ScanXGUI(m_pUI, m_pChildWnd);
if (m_pDlg)
{
pScanXDlg = m_pDlg;
// Register to receive events.
m_pQtApp->installEventFilter(m_pDlg);
// Display the UI.
m_pDlg->show();
ScanXGUIEnabledSem.release(1);
// Launch the message loop and do not return until thread closes.
m_pQtApp->exec();
// Ensure that the dialog box and class are destroyed.
// done() causes the local event loop to finish.
int CloseResult = 1;
m_pDlg->done(CloseResult);
delete m_pDlg;
m_pDlg = NULL;
}
#endif
delete m_pQtApp;
}
m_pQtApp = NULL;
}

d_stranz
5th December 2013, 02:00
I believe that the move, frame, and repaint functionality is actually being provided by the window system (i.e. Windows), not Qt, but I could be wrong about that. It sounds to me as though your Qt event loop isn't being set up correctly or that the Qt events are being intercepted by the driver app before they can get to your dialog.

You can probably check for an active event loop by implementing some kind of animation in your dialog (like a progress bar or a QTimer that changes something on timeout, for example) and seeing if it updates.

astodolski
5th December 2013, 12:53
I believe that the move, frame, and repaint functionality is actually being provided by the window system (i.e. Windows), not Qt, but I could be wrong about that. It sounds to me as though your Qt event loop isn't being set up correctly or that the Qt events are being intercepted by the driver app before they can get to your dialog.

You can probably check for an active event loop by implementing some kind of animation in your dialog (like a progress bar or a QTimer that changes something on timeout, for example) and seeing if it updates.

This all worked without issue in Qt 4.8.4. I am putting this out there in hopes that there are different considerations for what I am doing in Qt 5 as far as the GUI module is concerned.