Closing new nonchild window in Qt - qt

i'm trying to make 2 windows. 2nd should be called in 1st. I don't connect them child->parent.
But when i called 2nd window and closed it 1st window closed too. What should i do?
Both windows are inhereted from QWidget.
C++ and Qt
Sorry for my poor describe.
I have a main window. Class inherited from QMainWindow. That i created 2nd window. Class inherited from QWidget.
In first (main window) i'm creating and calling 2nd window
ConfigWindow *ConfWindow = new ConfigWindow();
ConfWindow->show();
Without giving link to parent. Everything works fine, but when i close 2nd window (config-window) my main window is closing too. I needn't in this. What should i do to block closing main window after config-window closing.
Hope describe a little better.
My first window has this flags:
this->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
Without them everything is fine. Could i change something if i need that flags in my window?

You need something like:
QApplication app(argc, argv);
app.setQuitOnLastWindowClosed(false);
Here is the test program: http://pastebin.com/f5903c5f4.
Beware, now you need to explicitly call quit() in the destructor of your main window.
If you read QApplication::quitOnLastWindowClosed documentation, you will find out that:
If this property is true, the applications quits when the last visible primary window (i.e. window with no parent) with the Qt::WA_QuitOnClose attribute set is closed. By default this attribute is set for all widgets except for sub-windows
Because your main window is a (frameless) tool window, it does count. That leaves ConfWindow as the only non sub-windows top-level widget. Thus, if you close ConfWindow, it provokes the application instance to quit.

If this is the code, then there is a huge bug in Qt.
The code above should never close your first Windows, there must be something else wrong.
Is the application closed or does it crash?
Remark
Who is deleting configWindow? There is a Qt::WA_DeleteOnClose attribute that deletes the window after it is closed.
ConfigWindow *confWindow = new configWindow();
configWindow->setAttribute(Qt::WA_DeleteOnClose, true);
confWindow->show();

Related

Qt is activating window without my consent after using QFileDialog

Qt 5.12.6 MSVC2017 64-bit on Windows 10, Qt Creator 4.10.1.
I have a top level window derived from QMainWindow, which has a QMdiArea.
From the first main window I use a file open dialog to open a new document in a QMdiSubWindow and place it in the QMdiArea. After the file dialog returns but before I do the logic of opening the document, I have to call QApplication::setActiveWindow(this), to set it back to the main window, because the opening logic depends on the active window. The need for this somewhat appears related to https://www.qtcentre.org/threads/2950-ActiveWindow-changes-after-closing-QFileDialog in that the activeWindow becomes null, regardless of how I parent the file dialog.
I then open a second identical top level window and open another document using the same method.
What's very weird is that after the second QMdiSubWindow in the second QMainWindow is activated, the first QMainWindow gets activated again, and thus various follow-on operations affect the document in the first window rather than the second window which is the intended one. If I click back and forth on the main windows, the activation is correct.
If I create a new document directly from the second QMainWindow instead of using the file open dialog, then it works fine. The new QMdiSubWindow is created and shown in the second QMainWindow, without the first one getting activated. So this implicates the file dialog somehow.
When I put a breakpoint on a function triggered by the QMainWindow::activated signal, the stack trace shows this signal is coming from within Qt on its own accord, not from someplace in my code directly.
How can I find out why Qt is activating the first window when using the file dialog from the second window? At this point the code is too large to try to fit a minimal example here on SO.
--EDIT--
I added a one-shot QTimer at the end of the function that creates the QMdiSubWindow. Zero milliseconds after in creates the QMdiSubWindow it activates the first QMainWindow, then activates the current QMainWindow. That workaround seems to work, and the second QMainWindow becomes the active one. But only if I select away from it first. The fact that the hack works with 0 ms timer is also interesting. I'll be posting minimal example when I can.
thanks

How to start second QDialog window on side of MainWindow?

I have a application in Qt, and a MainWindow. Now, I also added a helping QDialog which can be hooked up. This QDialog does not influence the programmflow, it just displays information.
But, it always starts on top of the MainWindow :/
SO I would like to start it on the side of the main window, so that it does not hinder the view to the main window?? How?
In my opinion , You should try this,
Use the overload of the QWidget::setParent() function to change the ownership of a QDialog widget, using set as NULL(but It will not share the parent's taskbar entry).
QDialog::show() returns control to the caller immediately, So it will not interfere in mainwindow flow.
Let's say, your application is in the full screen mode. Where then the QDialog should appear? It will be shown on the top and you won't be satisfied again.
If it doesn't influence the flow of the app then you are using it to communicate some sort of message. Can you use different ways? For instance, QStatusBar?
If not, why not to split the mainWindow with QSplitter or similar classes and provide an area where you can post all the info messages?
It sounds you want modaless dialog. In main window, use a slot to create the dialog.
void MainWindow::show_dialog()
{
if ( pDialog== NULL )
pDialog= new XYZ_Dialog(this);
QPoint p = pos();
QSize s = frameSize();
pDialog->setGeometry(p.x()+s.width(), p.y(), s.width()*1/2, s.height());
pDialog->show();
}
What I try to say is if the position of the new dialog bothers you, you set the position and size of it, before showing it.

Qt Main window loosing focus and going to background unexpectedly

Going up the learning curve and everything has been making sense so far except for this one:
I have a main window from where I call one or more dialog like this:
d->setWindowFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::FramelessWindowHint);
d->setGeometry(etc...
d->show();
The dialogs are not bound to the main window, and they are actually set to be displayed right beside the main window looking like an extension.
To close the dialogs I use a mouse 'enterEvent' on the mainwindow to send a close signal to the dialog(s) which will use hide().
void MainWidget::enterEvent(QEvent *event)
{
emit signal_related_close();
}
This works but randomly this causes a very annoying issue. When the signal is sent to close the dialogs, the main window would loose focus and go in the background (behind whatever application that is on the screen). Note that it does not minimize but only goes in the background and like I said it is random (about one out of 3 times I do it). I can't seem to get a pattern.
I initially thought the signal was messed up and instead used a dialog::leaveEvent() but that didn't help. I also tried using dialog::mouseMoveEvent and using that to hide the dialog but that would still randomly loose focus on the application.
The only method that doesn't loose focus is using a push button on each dialog that will initiate the same hide commands but that's not great for my UI. So it would seem that using the mouse enterEvent/leaveEvent,mouseMoveEvent will cause that random issue.
Anyone experienced this issue before? Any idea what could be wrong? Thx.
I can't explain why but this problem occurred when using QEvent or any mouse related event together with recursive children widgets. For example take this code in the parent widget constructor:
ChildWidget c1 = new ChildWidget (this);
ChildWidget c2 = new ChildWidget (c1);
Childwidget c3 = new ChildWidget (c2);
Using QEvent in the parent widget will randomly make the window go to the background and loose focus.
Setting all the ChildWidget to the same parent stopped the problem.

Attach Qt windows?

Is there any way to attach two Qt windows together? For example, if window A is the main window and window B is another widget I want to be able to show window B to the side of A and have both windows move together if the windows are dragged.
Not that I am aware of, but you can try following the trail of QMoveEvent. When a given widget is moved void QWidget::moveEvent ( QMoveEvent * event ) is called, and the QMoveEvent contains both old and new pos. Using this information, you can inject a move event in the other widget as well, and make it follow.
Of course, I am speaking of two independent widgets, each one in its own window. If they are contained, you don't need anything but a Layout management (see QLayout and related classes).
I don't work with Qt since a long time, so there could be a better method, but if I had to do it right now, this is the strategy I would use.
Also, I have the feeling that the QMoveEvent will be invoked only at start and end, unless you enable mouse tracking. If the former is the case, you will obtain that the other widget will "teleport" at the end of the move, instead of following smoothly.
You might be after something like this:
http://doc.qt.io/archives/4.6/qt4-mainwindow.html
Window A would be a QMainWindow and window B would be a QDockWidget.

Closed state of QDockWidgets not restored by restoreDockWidget?

I'm trying to get the positions and state of QDockWidgets saved/restored when the application is exited and relaunched. The flow in my main window is as follows:
restoreState(state.toByteArray());
// Dock widget gets created
restoreDockWidget(dockWidget);
This works great excepted for one thing: if dock widgets are closed when the application exits, they reappear into their last position the next time the application is run, while I'd expect them to have an initial hidden state. Is there something I missed about the usage of restoreDockWidget? Or should I handle the visible state of the dock widgets manually?
Update: Note that if I do as follows:
// Dock widget gets created
restoreState(state.toByteArray());
Then previously hidden widgets remain hidden. Unfortunately I cannot rely on this scheme as I have dock widgets that are created by plugins after the main window is restored.
Edit: seems to be fixed in latest Qt versions.
Examining Qt's code (version 4.5.0) revealed the following:
bool QDockAreaLayout::restoreDockWidget(QDockWidget *dockWidget)
{
...
dockWidget->show();
// dockWidget->setVisible(!placeHolder->hidden);
...
}
(Note that QDockAreaLayout is a private Qt class that is used by QMainWindow).
I'm not sure why the line to set the dock widget's visibility is commented-out and replaced with a line to show the dock widget every time. I also couldn't find a bug in the Qt Bug Tracker for this; it seems like a bug to me.
It looks like you'll have to manage the visibility of the dock widgets manually.

Resources