Closed state of QDockWidgets not restored by restoreDockWidget? - qt

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.

Related

Qt Widgets do not get showEvent() when tabbed in dock area of QMainWindow

In QMainWindow, when few widgets are tabbed together in dock area, how can I detect when a tab has been toggled by user? It is not a problem when I have an instance of QTabWidget created by myself and can attach a handler to currentChanged(), but what's about this case when the main window internally performs docking/tabifying operations? It normally would be showEvent() triggered but by some reason it doesn't work when tabs are switched. Also, a widget, not on active tab, has it's visibility state turned ON (isVisible() returns true) which is strange.
I found the answer. It is QMainWindow::tabifiedDockWidgetActivated() which is signaled when a tab on a docked widget changes. It was added in Qt 5.8. Without it there is no way.

Docking with QWinWidget: Adding DockWidgetAreas to QWidgets

I have an application utilizing QWinWidget in a Win32 window. I'd like to add DockWidgets and the associated behaviour to it. There don't seem to be any exposed APIs for adding custom DockAreas, and the latest docs are sparse beyond adding DockWidgets to a QMainWindow. Older docs imply there once was a public QDockArea class.
So far, my best option appears to be adding a neutered QMainWindow (no top-level status, no frame, etc.) to the QWinWidget and going from there (second source).
I was hoping there was a way to add DockAreas to any container, but it doesn't appear that way. As a side note, QWinWidget is used to have window manager control with our custom frame requirement, but if there's a pure QMainWindow/QWidget way to have the same result (with Qt::FramelessWindowHint), I'd be happy to switch over.
As I said in the comments, I've added within my QWinWidget in my Win32 window a QMainWindow field. That is:
class QWinWidget : public QWidget
{
...
QMainWidget* mainWidget;
}
QWinWidget::QWinWidget()
{
mainWidget = new QMainWindow(this);
mainWidget->setWindowFlags(Qt::Widget); //1
}
Note that while the docs and some forum posts (from this post) indicate you need to set window flags explicitly due to the QMainWindow constructor setting Qt::Window, I tested it without the setWindowFlags() line (marked with //1 above) without noticing anything wrong.
So, this gives me the nice QWinWidget window I spent so much time making, inside a frameless Win32 window, with a QMainWindow child and all the features that brings along with it. Docking, menu bar, status bar, etc.

Detecting click outside QWidget

My application has non-rectangular popup widgets.
their class defines the following to achieve that transparency:
setAttribute(Qt::WA_NoSystemBackground, true);
setAttribute(Qt::WA_TranslucentBackground, true);
I also use:
this->setWindowFlags(Qt::Popup| Qt::FramelessWindowHint);
The problem is that on windows 7, an automatic "shadow" is being drawn on the bottom and right sides of my window. This is highly undesirable.
So, I tried using Qt::Tool instead of Qt::Popup
this->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
This works visually. No shadow, but now a mouse click outside my widget window will not automatically close/hide it as it would have done with a Qt::Popup.
So, I need one of these two solutions:
A way to have Qt::Popup and get rid of that automatic windows shadow decoration
A way to let the Qt::Tool window a mouse click occurred outside of it.
One note: My application is built for Windows XP and up. I cannot use a Vista/Win7 only runtime DLLs, nor can i have a "Windows XP" and "Vista and up" separate builds.
Any advice will be welcome.
You could manually watch for when the focus changes from your Qt::Tool window. So basically you watch for when the focus goes onto another window of your process or when your application loses focus.
How to detect that my application lost focus in Qt?
Hope that helps.
Finally after realizing that no amount of "SetFocusPolicy" calls will allow me to receive those events for a Qt::Tool window, I've resorted to something else to fix my problem:
I kept the Qt:tool as Qt::Popup caused an undesired shadowing effect, tarnishing my owner draw frame. Removing this style cannot be done in Qt and I didn't want to mess with platform specific conditional code.
I installed an event filter with my Qt::tool window and I began receiving events that assisted me in understanding when other parts of my application were clicked, or if the application itself lost focus to another application. This was what I needed, functionality wise. I could also get an event when users click the non-client areas of the application's main window, such as the windows caption so that I can close it when dragging begins etc.
My solution for Windows 7:
QDialog *d = new QDialog;
d->setStyleSheet("background:transparent;");
d->setAttribute(Qt::WA_DeleteOnClose, true);
d->setAttribute(Qt::WA_TranslucentBackground, true);
#ifdef Q_OS_WIN
d->createWinId();
#endif
d->setWindowFlags(Qt::Popup | Qt::FramelessWindowHint);
d->show();
I set my QListView
d->setWindowFlags(Qt::Popup | Qt::FramelessWindowHint);
Install eventfilter and used MousePressEvent to hide qlistview widget.
MousePressEvent on list never comes to filter they produce other events which I didn't debug.
So if you want to design auto completer this will be perfect. Tested in Qt5.3.1.

Qt negative button not working

In my Qt symbian app, I have over ride the negative exit button with back to come back on main screen and then again over ride it with exit to close the app, my app is working fine on emulator but when I test it on device it shows exit button instead of back, some time it shows back also but if I go to the same page twice then again it start showing exit button, frustrating part is that app is working fine on Qt emulator but not on device. Does somebody knows whats the problem is. I am using
back->setSoftKeyRole(QAction::NegativeSoftKey);
this->addAction(back);
to over ride the exit button before loading the screen and
back->setSoftKeyRole(QAction::NegativeSoftKey);
this->removeAction(back);
to removing back button when coming back to mainWindow.
Create vertical layout and Widget which You will add on scrollarea with parent as that class this e.g
QVBoxLayout *vlay = new QVBoxLayout(this);
QWidget *area = new QWidget(this)
And add widget to it
This will make it child of parent class.
works fine for me.
I think adding and removing QAction objects here and there is asking for problems.
You should try to redesign your application to use a QStateMachine to handle transitions between states.
Take a look at the introductory documentation here.
Refer this LINK for custom softkeys..
QAction* myAction= new QAction(tr("My Action"), this);
myAction->setSoftKeyRole(QAction::NegativeSoftKey);
addAction(myAction);

Closing new nonchild window in 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();

Resources