PyQt4: the window appears in a different position after hide () and show ()

Using PyQt4, when I hide the window and show it later, it appears in a different position (at least here on Linux). Code example:

#!/usr/bin/python3 from PyQt4.QtGui import * app = QApplication([]) widget = QWidget() widget.setLayout(QVBoxLayout()) label = QLabel() widget.layout().addWidget(label) def hideShow(): widget.hide() widget.show() widget.layout().addWidget(QPushButton('Hide/Show', clicked = hideShow)) widget.show() app.exec_() 

The window disappears and appears, but slightly lower and to the right of the starting position. I think it is offset by the size of the window manager window around the actual widget.

How to place a window in the place where it was? And why is this even moving? Shouldn't he stay where he is?

+6
source share
2 answers

On Linux, window placement can be very unpredictable. See this section in the Qt documentation for a breakdown of the problems.

There is probably no general solution to the problem, but for me, setting up the geometry before the initial show() works:

 ... widget.setGeometry(200, 200, 100, 50) widget.show() app.exec_() 

UPDATE

After some testing with the KDE window manager, I might have discovered a potential solution.

It seems that calling show() immediately after hide() does not give the window manager enough time to calculate the correct position of the window. Therefore, a simple way is to explicitly set the geometry after a short delay:

 from PyQt4.QtGui import * from PyQt4.QtCore import QTimer app = QApplication([]) widget = QWidget() widget.setLayout(QVBoxLayout()) label = QLabel() widget.layout().addWidget(label) def hideShow(): widget.hide() QTimer.singleShot(25, showWidget) def showWidget(): widget.setGeometry(widget.geometry()) widget.show() widget.layout().addWidget(QPushButton('Hide/Show', clicked = hideShow)) widget.show() app.exec_() 

This works for me using KDE-4.8 and OpenBox, but of course YMMV.

+2
source

I had a similar problem with xfce. Perhaps you could get the position before hiding it (or when displaying it, depending on what you want), save it, and then set when it is displayed again using setGeometry ()? A bit hacked, maybe ..

0
source

All Articles