I have an Mfc application where I want to open a Qt modal window, while the Mfc application is still running behind.
To start a Qt application from an Mfc, I got the how to there. This page creates a Dll but my solution creates a static library instead.
As for creating a Qt modal window with main application running behind, it looks easy.
My problem is that it looks like that I cannot combined both solution.
The following code starts the Qt window, but I strongly suspect that I am blocking my main thread and main thread is not able to receive events.
void QtMfcFacade::startDevicesConfigurationWizard(HWND hWnd)
{
QWinWidget win( hWnd );
win.showCentered();
DevicesConfigurationWizard devicesConfigurationWizardUI(&win);
devicesConfigurationWizardUI.exec();
}
exec function is probably blocking main thread
Following solution should not block main thread, but the Qt windows appears only for few miliseconds and disappeared
void QtMfcFacade::startDevicesConfigurationWizard(HWND hWnd)
{
QWinWidget win( hWnd );
win.showCentered();
DevicesConfigurationWizard devicesConfigurationWizardUI(&win);
devicesConfigurationWizardUI.show();
}
So, the question is, is it possible to use show function instead of exec function?
(This works if I am creating a Dll and calling the Dll in a worker thread from my Mfc application, but I do prefer using static library)
I did not read enough the walkthough.
It is said : "Since we want the dialog to be modeless we cannot create the QWinWidget on the stack, since it would be deleted when it leaves the scope, and all its children, including the dialog, would be deleted as well. Instead we create QWinWidget on the heap, using operator new"
So, to make my window non modal while giving control back to main thread, I should do this :
void QtMfcFacade::startDevicesConfigurationWizard(HWND hWnd)
{
QWinWidget *win = new QWinWidget( hWnd );
win->showCentered();
DevicesConfigurationWizard devicesConfigurationWizardUI = new DevicesConfigurationWizard (win);
devicesConfigurationWizardUI->show();
}
Related
i have a Qt project with mainwindow (GUI Application)
how can i communicate with my main via my form?
for example
increase variable (which there's in my main) while button a click in my form
i have make a project in C which its in console application. works fine, and now i make another project which contains ui form with same code. and i want to make communication between form and main function
You can use the Qt signal/slot functionality.
Example:
// on mainwindow.cpp. Delcare onButtonClicked as a slot() on the header
void onButtonClicked()
{
++myVar;
}
connect(myButton, SIGNAL(clicked()), this, SLOT(onButtonClicked());
Reference docs.
I have an application where in the mainWindow(inherited from QMainWindow) creates a childWindow(also inherited from QMainWindow) and when run, both windows are launched with the childWindow masking the mainWindow.
In the mainWindow() constructor I have
setCentralWidget(this);
On Linux when the mainWindow->titleBar is clicked, the mainWindow is brought to the front whereas on Windows this doesn't seem to work.
To get a consistent behavior across platforms, I added a installEventFilter() and mouseEventHandler to account for left-button mouse events, but again none of methods I used within the mouse event handler helped me achieve the behavior I needed.
void mainWindow::mouseReleaseEvent(QMouseEvent* mevent)
{
if (Qt::LeftButton == mevent->button())
{
//this->raise();
//this->show();
//setCentralWidget(this);
}
}
How can I switch to the mainWindow() when I press(mouse-event) the Title bar?
Is there a reason why the behavior is different on Windows and Linux and how I do I make it consistent? I'm using the opensource versions of Qt-4.8.4 for Windows and Linux.
Have you tried using this function yet?
http://doc.qt.io/qt-4.8/qwidget.html#stackUnder
and I would use this in tandem with QFocusEvent
http://doc.qt.io/qt-4.8/qwidget.html#focusInEvent
http://doc.qt.io/qt-4.8/qfocusevent.html#details
I recreated the example of a webkit that displays the content of a textEdit containing HTML: http://qt-project.org/doc/qt-4.8/webkit-previewer.html
I changed it so rather than the webkit HTML being changed upon clicking the button, it's changed upon the text in the textEdit being changed:
// changed when button is click. Works fine.
void Previewer::on_previewButton_clicked()
{
// Update the contents in web viewer
QString text = htmlTextEdit->toPlainText();
webView->setHtml(text);
}
// change when text is changed. Crashes.
void Previewer::on_htmlTextEdit_textChanged()
{
// Update the contents in web viewer
QString text = "<html><body><h1>No crash!</h1></body></html>";
webView->setHtml(text);
}
This causes the program to crash as soon as it starts. I altered the program to run the function only a bit later (I thought maybe something needed to be initialized) but it still crashed once it reached the textChanged function. Why is it crashing? How can I fix this?
Your program is entering an infinite loop because, in the example, there's a connection between the webView's loadFinished(bool) signal and the text/html editor's updateTextEdit() slot.
Basically, editing the HTML causes the page to load again, which causes an update to the editor, which causes the page to load again, so on and so forth.
A quick way I solved this was to add a static bool flag to the updateTextEdit SLOT/function that only allows it to run once.
void MainWindow::updateTextEdit()
{
static bool once = false;
if (once) {
return;
}
once = true;
QWebFrame *mainFrame = centralWidget->webView->page()->mainFrame();
QString frameText = mainFrame->toHtml();
centralWidget->plainTextEdit->setPlainText(frameText);
}
Doing this worked for me, but your version might work differently than mine. I followed the example closely, but added an htmlchanged() slot to the previewer class, and made the connection like so:
connect(centralWidget->plainTextEdit, SIGNAL(textChanged()), centralWidget, SLOT(html_changed()));
Also, I'm no expert, but I'm pretty sure this is not the best way to get around this, and I assume that updateTextEdit() needs to run more than once. It'll work for the time being, though.
I am trying to move my QSystemTrayIcon module to a separate thread. I am getting the below error while running the application. The Initialize() method addAction causing the error.
QWidget: Must construct a QApplication before a QPaintDevice
My sample code snippets:
Declared the global variable
QMenu myMenu;
Member Variable in the header file
QAction* openFile;
In the constructor
openFile = new QAction(parent);
Initialize()
{
myMenu.addAction(openFile);
}
void myApp::run()
{
Initialize()
}
You must not use any GUI-related classes outside your main thread, i.e. the one QApplication was created in. Hence you cannot move your QSystemTrayIcon stuff in a separate thread. And no, there is no workaround.
You are approaching this problem backwards. The reason that "The TrayIcon menus are not displaying if some functionality is running at the background Menus will display after the process completion." is because you are blocking the GUI thread when you wait for things. Do not block the GUI thread by waiting on things. Most of Qt provides signals that fire when things get accomplished (when they succeed or fail). Those are the nonblocking APIs that you should be using.
Good day!
Have a problem: main window (MyApp for example) works in background (behind all other windows or in tray), not necessary to show it without need. After some period of time some reminding StayOnTop dialog appears (having parent = 0, to be not tied to main window) and asks for some user interactions. After dialog closes I’d like to keep an application window user currently working with active, and user continue do his job not switching to MyApp. However, instead of above behaviour, main MyApp window appears and user forces to switch back to his window (job) – inconvenient.
How to prevent MyApp main window appearing after closing the dialog? Need to install some event filter or access OS API? Problem exists in Mac, Windows, Linux.
You could try to re-implement the main window's showEvent and ignore that event, in case other windows are visible.
void main_window::showEvent( QShowEvent* e )
{
if( /*one or more of its children are visible */ )
{
// nothing to do
}
else
{
QMainWindow::showEvent( e );
}
}
Maybe just try invoking hide method after dialog call? Other possibility - try setting this:
http://doc.qt.io/qt-4.8/qwidget.html#windowFlags-prop to Qt::Popup.