Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt QWidget Geometry()未更新_Qt_Pyside_Qwidget - Fatal编程技术网

Qt QWidget Geometry()未更新

Qt QWidget Geometry()未更新,qt,pyside,qwidget,Qt,Pyside,Qwidget,我有QWidgets在QVBoxLayout中排列在qscrollara中,带有setwidgetResizeable(True) 当我调整其中一个QWidgets的大小时,QWidgets会在图形用户界面中相应地重新定位,但是它们的geometry()属性没有反映这一点,geometry().x()和geometry()在重新定位前后都保持不变 到目前为止,我找到的唯一更新x()和y()坐标的方法是hide()和show()qscrollara 我尝试了update(),updateGeome

我有
QWidget
s在
QVBoxLayout
中排列在
qscrollara
中,带有
setwidgetResizeable(True)

当我调整其中一个
QWidget
s的大小时,
QWidget
s会在图形用户界面中相应地重新定位,但是它们的
geometry()
属性没有反映这一点,
geometry().x()
geometry()
在重新定位前后都保持不变

到目前为止,我找到的唯一更新
x()
y()
坐标的方法是
hide()
show()
qscrollara

我尝试了
update()
updateGeometry()
repaint()
,但没有成功

下面是我用来总结问题的示例测试代码:

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()
我的问题是:

  • 有更好的解决办法吗
  • updateGeometry()
    不应该实际更新
    geometry()
  • 为什么会发生这种行为?(即,为什么它以图形方式更新,而不是以编程方式更新?)
  • 连续使用
    hide()
    show()
    是否会在其他上下文中导致一些问题(窗口闪烁或其他

  • 当您更新GUI时,它不是即时的。将控件交给事件循环时将执行此操作。在本例中,它是在
    \uuuu init\uuuu
    完成之后完成的,这显然是在所有
    打印之后完成的。因此,您将看到旧的位置

    隐藏/显示
    强制在该点进行更新。这就是为什么你会得到正确的值。但是,这不是最好的方法,因为在
    hide/show
    执行其工作时,您可能会观察到闪烁

    更好的方法是告诉事件循环在继续之前处理事件。这将确保GUI得到更新:

        #...
        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:我想你有充分的理由这么做。大多数情况下,您不会在意GUI何时更新。

    在本例中,QScrollArea是如何添加到VLayout的?实际上,布局是针对QWidget的,QWidget是QScrollArea的内部小部件。QScrollArea不是任何布局的一部分。谢谢,这解决了我的问题。还有一件事我不明白,GUI如何在不更新
    geometry().x()
    geometry().y()
    值的情况下进行自我更新?通常情况下,情况正好相反(即代码更新而非GUI)?@IlyesFerchiou:当您调用
    self.test\u 1.setFixedHeight(1000)
    时,GUI和
    几何体都不会更新。
    几何图形的可视化更新或重新计算不是即时的。它是“排队的”。一旦Qt事件循环有机会处理这些事件,就会执行更新
    .processEvents()
    基本上“暂停”了
    \uuuu init\uuuu
    ,并让Qt事件循环处理这些更新事件。换句话说,在原始版本中,在这些打印调用之间GUI不会更新。这是事后发生的。