QGraphicsView尺寸与预期不符
我通过Qt Designer创建了两个标签页,每个标签页里都有一个QGraphicsView。当默认选择的是第二个标签页时,两个标签页的大小是一样的,正如我所期待的那样。然而,当默认选择第一个标签页时,它们的大小就不一样了(没有理由?!)。有什么建议吗?
提前谢谢你。
编辑(提供示例代码及其输出):
<!-- language: python -->
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled.ui'
#
# Created: Wed Apr 23 16:55:00 2014
# by: PyQt4 UI code generator 4.10
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.resize(800, 600)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
self.tabWidget = QtGui.QTabWidget(self.centralwidget)
self.tabWidget.setObjectName(_fromUtf8("tabWidget"))
self.tab = QtGui.QWidget()
self.tab.setObjectName(_fromUtf8("tab"))
self.verticalLayout_2 = QtGui.QVBoxLayout(self.tab)
self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
self.graphicsView = QtGui.QGraphicsView(self.tab)
self.graphicsView.setObjectName(_fromUtf8("graphicsView"))
self.verticalLayout_2.addWidget(self.graphicsView)
self.tabWidget.addTab(self.tab, _fromUtf8(""))
self.tab_2 = QtGui.QWidget()
self.tab_2.setObjectName(_fromUtf8("tab_2"))
self.verticalLayout_3 = QtGui.QVBoxLayout(self.tab_2)
self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3"))
self.graphicsView_2 = QtGui.QGraphicsView(self.tab_2)
self.graphicsView_2.setObjectName(_fromUtf8("graphicsView_2"))
self.verticalLayout_3.addWidget(self.graphicsView_2)
self.tabWidget.addTab(self.tab_2, _fromUtf8(""))
self.tab_3 = QtGui.QWidget()
self.tab_3.setObjectName(_fromUtf8("tab_3"))
self.verticalLayout_4 = QtGui.QVBoxLayout(self.tab_3)
self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4"))
self.graphicsView_3 = QtGui.QGraphicsView(self.tab_3)
self.graphicsView_3.setObjectName(_fromUtf8("graphicsView_3"))
self.verticalLayout_4.addWidget(self.graphicsView_3)
self.tabWidget.addTab(self.tab_3, _fromUtf8(""))
self.verticalLayout.addWidget(self.tabWidget)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 25))
self.menubar.setObjectName(_fromUtf8("menubar"))
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName(_fromUtf8("statusbar"))
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
self.tabWidget.setCurrentIndex(2)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
# printing sizes *************************************
print self.tab.size()
print self.tab_2.size()
print self.tab_3.size()
print self.graphicsView.size()
print self.graphicsView_2.size()
print self.graphicsView_3.size()
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Tab 1", None))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Tab 2", None))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("MainWindow", "Tab 3", None))
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.showMaximized()
sys.exit(app.exec_())
输出:
PyQt4.QtCore.QSize(640, 480)
PyQt4.QtCore.QSize(640, 480)
PyQt4.QtCore.QSize(640, 480)
PyQt4.QtCore.QSize(622, 462)
PyQt4.QtCore.QSize(100, 30)
PyQt4.QtCore.QSize(622, 462)
1 个回答
一种可能性是,Qt 只在需要的时候才创建标签页。所以当启动时选择了标签页 1,标签页 2 还不存在。如果启动时选择了标签页 2,我不知道标签页 1 是否已经存在(因为它是默认的标签页)。如果存在,那么在启动时选择标签页 2 时,Qt 就有了两个标签页的大小信息,但如果启动时选择的是标签页 1,Qt 只知道标签页 1 的大小信息。
你可以尝试让所有标签页都提前创建,这里有个关于 PyQt 的帖子 QObject::findChild() returns None without obvious reason,讨论了相关的问题和解决办法。
更新:
我测试了你的代码,确认在 PyQt5 中也是同样的情况。构造后,尚未选择的标签页的大小是错误的。然而,一旦选择了某个标签页,它就会被布局,大小也会变得正确。要看到这一点,可以注释掉这一行 self.tabWidget.setCurrentIndex(0)
,并把下面的三行
print self.graphicsView.size()
print self.graphicsView_2.size()
print self.graphicsView_3.size()
改成这样(缩进很重要:我把这三条打印语句移到了一个新的 printViewSizes
方法中,并添加了一个标签切换观察者):
self.tabWidget.currentChanged.connect(self.onTabChange)
self.printViewSizes()
然后添加以下两个方法:
def printViewSizes(self):
print(self.graphicsView.size())
print(self.graphicsView_2.size())
print(self.graphicsView_3.size())
def onTabChange(self):
print('Tab changed')
self.printViewSizes()
现在在窗口可见后,点击标签页 2,然后是标签页 3。输出结果是:
PyQt5.QtCore.QSize(640, 480)
PyQt5.QtCore.QSize(640, 480)
PyQt5.QtCore.QSize(640, 480)
PyQt5.QtCore.QSize(622, 462)
PyQt5.QtCore.QSize(100, 30)
PyQt5.QtCore.QSize(100, 30)
Tab changed
PyQt5.QtCore.QSize(758, 518)
PyQt5.QtCore.QSize(758, 518)
PyQt5.QtCore.QSize(100, 30)
Tab changed
PyQt5.QtCore.QSize(758, 518)
PyQt5.QtCore.QSize(758, 518)
PyQt5.QtCore.QSize(758, 518)
这表明标签页 2 一旦可见,大小就正确了,然后标签页 3 一旦可见,大小也正确了。所以如果你在标签页中遇到布局问题,这不是问题的根源,可能是在你图形视图中的某个小部件的大小调整处理程序中。