Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyQt4: Window shows up at another position after hide() and show()

Using PyQt4, when I hide a window and show it afterwards, it appears at another position (at least here on Linux). Example code:

#!/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 a bit below and to the right of the original position. I think it's displaced by the size of the window manager's frame around the actual widget.

How can I place the window at the exact position where it was? And why does it move at all? Shouldn't it stay where it is?

like image 798
Tobias Leupold Avatar asked Nov 19 '12 20:11

Tobias Leupold


1 Answers

On Linux, window placement can be very unpredictable. See this section in the Qt documentation for a break-down of the issues.

There's probably no general solution to the problem, but for me, setting the geometry before the initial show() seems to work:

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

UPDATE

After some testing with the KDE window manager, I may 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 window position. So a simple workaround is to explicitly set the geometry after a small 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.

like image 148
ekhumoro Avatar answered Oct 18 '22 15:10

ekhumoro