Reputation: 583
I have QWidget
s lined up in a QVBoxLayout
inside a QScrollArea
with setWidgetResizable(True)
When I resize one of the QWidget
s, the QWidget
s relocate themselves accordingly in the graphical user interface, but their geometry()
property doesn't reflect that, geometry().x()
and geometry().y()
both remain the same before and after relocation.
The only method I have found so far to update the x()
and y()
coordinates is to hide()
and show()
the QScrollArea
.
I have tried update()
, updateGeometry()
and repaint()
without any success.
Here is a sample test code that I made to summarize the problem :
import sys
from PySide import QtGui, QtCore
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.showMaximized()
self.widget_window = QtGui.QWidget()
self.scrollarea = QtGui.QScrollArea()
self.v_layout = QtGui.QVBoxLayout()
self.test_1 = QtGui.QPushButton('Test 1')
self.test_2 = QtGui.QPushButton('Test 2')
self.v_layout.addWidget(self.test_1)
self.v_layout.addWidget(self.test_2)
self.widget_window.setLayout(self.v_layout)
self.scrollarea.setWidgetResizable(True)
self.scrollarea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.scrollarea.setAlignment(QtCore.Qt.AlignCenter)
self.scrollarea.setWidget(self.widget_window)
self.setCentralWidget(self.scrollarea)
print(self.test_2.geometry().x())
print(self.test_2.geometry().y())
self.test_1.setFixedHeight(1000)
#uncommenting the following next two lines, solves the problem
#self.scrollarea.hide()
#self.scrollarea.show()
print(self.test_2.geometry().x())
print(self.test_2.geometry().y())
def main():
app = QtGui.QApplication(sys.argv)
main = MainWindow()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
My questions are :
updateGeometry()
supposed to actually update the geometry()
?hide()
and show()
successively cause some problems in other contexts (window flickering or something else...) ?Upvotes: 2
Views: 3751
Reputation: 36715
When you update the GUI, it's not instantaneous. It's performed when you give the control to the event loop. In this case, it's done after __init__
completes, which is obviously after all your print
s. Therefore, you'll see the old position.
hide/show
forces an update at that point. That's why you get correct values. However, this is not the best way, because you might observe flicker while hide/show
does its job.
Better way would be telling the event loop to process events before continuing. This will ensure that the GUI is updated:
#...
print(self.test_2.geometry().x())
print(self.test_2.geometry().y())
self.test_1.setFixedHeight(1000)
QtGui.QApplication.processEvents()
print(self.test_2.geometry().x())
print(self.test_2.geometry().y())
#...
PS: I'm assuming, you have good reasons to do this. Most of the time, you won't care when the GUI is updated.
Upvotes: 2