Deal with window state in MdiArea - qt

I use in my app a MDI central widget. Currently I always open a child as maximized
child->showMaximized();
This cause problems if I use cascaded or tiled workspace.
Now I tried to find out if the subwindows are maximized or not. If not I want to open them in
child->showNormal();
But the snippet:
foreach(QWidget* widget, mdiArea->subWindowList()) {
if(widget->windowState()==Qt::WindowMaximized){
qDebug("maximized");
}else{
qDebug("not maximized");
}
}
It looks that this subwindow will only have WindowActive and WindowNoState.
Any idea how to check if the subwindow (child) is maximized or not?
With maximized I talk about the full mdiArea (Workspace)

windowState() returns a set of flags, so for example windowState() can indicate that a window is active (Qt::WindowActive) and maximized (Qt::WindowMaximized), so if you want to verify if one of them is active you must use the operator "&":
if(widget->windowState() & Qt::WindowMaximized)

Related

Qt: "normal" window size lost when switching to maximized state and then to fullscreen

I have an Qt application that can be displayed either "normal" (a normal window that's neither maximized nor minimized), maximized or fullscreen. I achieve that by calling the functions QWidget::showNormal(), QWidget::showMaximized() and QWidget::showFullscreen().
Let me first of all explain what does work:
Going from normal to maximized and back works. Qt remembers the window size and position of the normal window and then restores that when exiting the maximized state.
Going from normal to fullscreen and back works. Also here the size and position of the normal window is maintained.
What doesn't work?
When going from normal to maximized, then to fullscreen, back to maximized and then back to normal that does not work as expected. The window will not be resized to the size that it had originally, before maximizing. Instead the window will be as large as the screen (basically as large as the OS allows the window to be).
If I now go to fullscreen again then in the right upper corner and on the bottom edge there are weird artifacts that seem to look like parts of an old Vista window frame with visual effects disabled.
Here is an image that should illustrate the process I just explained:
I tried to save the last size of the window using QWidget::saveGeometry() or just saving the size obtained by QWidget::size() when a window state change event occured, but there were always cases when it behaved strangely. Apart from that, that last step when going full screen again looks like a bug to me.
What do you think?
UPDATE:
If I resize the window manually (to an arbitrary size) before the last step (which is going to fullscreen again), the fullscreen works without problems.
Try doing showNormal() before showFullScreen() when the window is maximised and going to fullscreen.
when going to fullscreen
if (wasMaximized = isMaximized())
{
setVisible(false); // prevents window animation on showNormal() call
showNormal();
setVisible(true);
}
showFullScreen();
when returning from fullscreen
if (isFullScreen())
{
if (wasMaximized)
showMaximized();
else
showNormal();
}
The new Qt 5.6 release apparently fixed that bug.
This will helpful for you
void toggleFullScreen()
{
if (isFullScreen()) {
if (wasMaximized) {
showMaximized();
} else {
showNormal();
}
} else {
wasMaximized = isMaximized();
showFullScreen();
}
}
You need to declare wasMaximized yourself (It must be a global variable for you MainWindow class)
I have a bad English, so I can't explain all of this code. Sorry

Modeless Qt window on top of parent, but not on top of other applications

I wish to have a Qt dialog window that:
always stays on top of its parent (the main application window),
allows the user to interact with the parent window, and
does not always stay on top of other applications.
I've been able to achieve 1 and 3 by making the dialog modal, and I can achieve 1 and 2 by using the Qt::WindowStaysOnTopHint window flag. But I cannot manage to make all three work - is it possible?
In case answers are OS-specific, I mainly work on a Mac, but I would prefer a solution that also applies to Windows and Linux. Thanks!
You could try to use QGuiApplication::applicationStateChanged. This way you get notified if the user enters or leaves your application. Just dynamically add and remove the Qt::WindowStaysOnTopHint flag for your window. If you have multiple windows, you can use QGuiApplication::focusWindowChanged together with the first one.
Edit: To make the dialog non-modal, either set NULL as it's parent, or set the windowModality-Property to Qt::NonModal and show the dialog using show and not open or exec
Example code in a subclass of QDialog:
connect(QApplication::instance(), SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(changeAlwaysOnTop(Qt::ApplicationState)));
...
void MyDialog::changeAlwaysOnTop(Qt::ApplicationState state)
{
if (state == Qt::ApplicationActive)
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
else
setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
show();
}
The default QWidget is enough for your needs.
If you create QWidget with parent to your mainwindow it will be on top of other widgets. You just have to create it last or stack it properly with QWidget::raise().
I know I already posted an answere, but I found the best solution:
Use QDockWidget. A DockWidget will always stay on top of it's parent, and if you set the allowedAreas property to Qt::NoDockWidgetArea, the window will behave the way you need it!
QMessageBox Inherits QDialog, the following code statify all requirements
msgBox = new QMessageBox(QApplication::activeWindow());
msgBox->setModal(false);
msgBox->setWindowFlags(msgBox->windowFlags() | Qt::WindowStaysOnTopHint);
msgBox->show()
This window will be always on top:
self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.WindowStaysOnTopHint)
Or you can pass your existing flags:
self.setWindowFlags( self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
I can reproduce the original problem only if the QDialog is created with a NULL parent. Otherwise the following lines are sufficient to accomodate requirement 1, 2 and 3.
dlg=new MyDialog(applicationMainWidget);
dlg->show();

Dockable window -- not maximise

I have made a gui which contains dockable windows.
If i click on maximize square on the docable window it comes out but does not occupies the full screen of my gui.
Example if i click syntax window it does not occupy full screen
Which property do i have to change to make docable window to occupy full screen ?
Please see the attached image.
You will need to create your own TitleBarWidget and set it with:
void QDockWidget::setTitleBarWidget ( QWidget * widget )
So you will be able to have as many buttons as you want and maximize it. Following code will help you with it:
QDockWidget *dockWidget = qobject_cast<QDockWidget*>(parentWidget());
dockWidget->showMaximized();
Edit: To keep the 2 existing buttons functionality:
The docking will be done with setFloating(bool ). So:
QDockWidget *dockWidget = qobject_cast<QDockWidget*>(parentWidget());
dockWidget->setFloating( !dockWidget->isFloating () );
For the close, parent close() method will work.
And, last edit, i promise ;).
You will need to have the title to show it on your titleWidget:
And it is in windowTitle : QString property of parent:

Finger Scrolling in QT?

I have implemented Finger Scrolling to one of my QListWidget.
I have taken refernce from
http://www.developer.nokia.com/Community/Wiki/Qt_Kinetic_scrolling_-_from_idea_to_implementation
Now the problem is on_current_row_changed event of QListWidget gets fired when i scroll up and down my List.
How i can avoid this on click only it should behave like click not on Scroll.
Starting from Qt5 this is as simple as:
#include <QScroller>
...
QScroller::grabGesture(myListWidget, QScroller::LeftMouseButtonGesture);
For touch screens use TouchGesture instead of LeftMouseButtonGesture.
If the widget doesn't inherit QAbstractScrollArea (e.g. QWebView):
QScrollArea *scrollArea = new QScrollArea;
scrollArea->setWidget(myWidget);
QScroller::grabGesture(scrollArea, QScroller::LeftMouseButtonGesture);
Be sure to resize the widget to its content size.
You need to test whether the finger has moved between mousePress and mouseRelease. You can extract the position of the press, so if you store it in an intermediate variable, then test it against the position of the mouseRelease (say using QPoint::manhattanLength()), you can tell whether the finger has moved. If it has, the user is scrolling, if not, they're clicking.
EDIT: Looking at the code you've linked to, they're already doing the above. Could we see some more of your reimplemenation?

How to make Qt::Tool not stay on top of the main window

I have problem with Qt::Tool flag. When I create new widget with Qt::Tool flag it appears on top of the main window. But when I switch back to main window and make it active the I still have the tool widget in front so it my main window is not fully visible.
Qt::WindowStaysOnTopHint is not active.
Just in case - environment is KDE4
Thanks in advance.
That's kind of the point of a tool window - to stay on top automatically. If you want an otherwise normal window but without a titlebar, do that instead of making a tool window (i.e. unset Qt::WindowTitleHint in the window's flags - either by using the (QWidget* parent, Qt::WindowFlags f) constructor or the setWindowFlags method).

Resources