【问题标题】:Python PyQt/PySide QMdiArea subwindows scroll not working in TabbedViewPython PyQt/PySide QMdiArea 子窗口滚动在 TabbedView 中不起作用
【发布时间】:2013-08-23 15:49:58
【问题描述】:

我已经使用 PyQt 设计器设置了简单的示例。见下文。 我有 mdiarea,我在其中添加了一个表单作为子窗口。我使窗体比主窗口长一点,以查看子子窗口是否出现滚动条。

问题: 如果我将 mdiarea 设置为 setViewMode(QtGui.QMdiArea.TabbedView) 滚动条停止工作并消失。 Howeevr 如果我不使用 TabbedView,滚动条可以正常工作。 谁能告诉我怎么了?我需要带有工作滚动条的 mdiarea 的 TabbedView。

我在 win7 上使用 Python 2.7、PyQT 4.8.4/PySide 1.2.1。

Python 示例代码: 注释 self.mdiArea.setViewMode 行以查看示例工作。

import sys
from PyQt4 import QtCore, QtGui

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName( "MainWindow" )
        MainWindow.resize(500, 400)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName( "centralwidget" )
        self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName( "verticalLayout" )
        self.mdiArea = QtGui.QMdiArea(self.centralwidget)
        self.mdiArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
        self.mdiArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
        self.mdiArea.setActivationOrder(QtGui.QMdiArea.CreationOrder)
        self.mdiArea.setViewMode(QtGui.QMdiArea.TabbedView)
        self.mdiArea.setTabsClosable(True)
        self.mdiArea.setTabsMovable(True)
        self.mdiArea.setObjectName( "mdiArea" )
        self.verticalLayout.addWidget(self.mdiArea)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 508, 21))
        self.menubar.setObjectName( "menubar" )
        self.menuAdd = QtGui.QMenu(self.menubar)
        self.menuAdd.setObjectName( "menuAdd" )
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName( "statusbar" )
        MainWindow.setStatusBar(self.statusbar)
        self.menubar.addAction(self.menuAdd.menuAction())

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(   "MainWindow" )
        self.menuAdd.setTitle( "&Add Form" )

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName( ("Form"))
        Form.resize(400, 800)
        self.gridLayout = QtGui.QGridLayout(Form)
        self.gridLayout.setObjectName( ("gridLayout"))
        self.plainTextEdit = QtGui.QPlainTextEdit(Form)
        self.plainTextEdit.setMinimumSize(QtCore.QSize(0, 731))
        self.plainTextEdit.setObjectName( ("plainTextEdit"))
        self.gridLayout.addWidget(self.plainTextEdit, 0, 0, 1, 1)
        self.buttonBox = QtGui.QDialogButtonBox(Form)
        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
        self.buttonBox.setObjectName( ("buttonBox"))
        self.gridLayout.addWidget(self.buttonBox, 1, 0, 1, 1)

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        Form.setWindowTitle( "Lengthy subwindow" )
        self.plainTextEdit.setPlainText( "Lengthy Form" ) 


class MyApp(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MyApp, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

    def Add_Subwindow(self):
        widget = QtGui.QWidget()
        self.subwin_abq = Ui_Form()
        self.subwin_abq.setupUi(widget)
        self.subwindow = QtGui.QMdiSubWindow(self.ui.mdiArea) 
        widget.setParent(self.subwindow)
        self.subwindow.setWidget(widget)  
        self.subwindow.setWindowTitle("testing")
        self.ui.mdiArea.addSubWindow(self.subwindow)
        widget.show()
        self.subwindow.show()
        self.subwindow.widget().show()

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = MyApp()
    window.show()
    window.Add_Subwindow()
    sys.exit(app.exec_())

【问题讨论】:

    标签: python-2.7 pyqt4 pyside qmdiarea


    【解决方案1】:

    只是想对 OP 中的代码表示感谢 - 在 PyQT 中寻找一个简单的 MDI 示例,你的帮助我很多!我没有确切的答案,但这是我到目前为止可以注意到的:我有 Python 2.7,PyQT 4.8.3,只需评论 setTabsClosablesetTabsMovable 行,我就可以让你的例子展示像这样:

    我下载了designer-qt4 并在那里查看了QMdiArea,似乎没有什么叫TabbedView。所以我发现了这个:

    QtWidgets 5.0: QMdiArea Class | Documentation | Qt Project

    枚举 ViewMode { SubWindowView, TabbedView }
    这个枚举描述了区域的视图模式;即如何显示子窗口。
    SubWindowView 0 显示带有窗口框架的子窗口(默认)。
    TabbedView 1 在标签栏中显示带有标签的子窗口。
    documentMode:该属性保存标签栏在标签视图模式下是否设置为文档模式。

    我的阅读方式:或者您可以以 MDI 方式显示子窗口(因此它们可以比窗口大,带有滚动条)或者子窗口变成选项卡在选项卡式视图中 - 子窗口的大小不再重要,因此它会扩展以占用可用的选项卡式区域。此外,在您的代码中,self.ui.mdiArea.documentMode() 在这两种情况下都会返回 False

    我还在你的MyApp.Add_Subwindow() 末尾添加了这个 sn-p:

        sp = self.subwindow.sizePolicy()
        print sp.__dict__
        #print dir(sp)
        for attr in dir(sp):
          try:
            print "obj.%s = %s" % (attr, getattr(sp, attr))
          except: pass
    

    这会转储一些有趣的数据(不过我不确定这些是否是对象属性):

    obj.ButtonBox = 2
    obj.CheckBox = 4
    obj.ComboBox = 8
    obj.ControlType = <class 'PyQt4.QtGui.ControlType'>
    obj.ControlTypes = <class 'PyQt4.QtGui.ControlTypes'>
    obj.DefaultType = 1
    obj.ExpandFlag = 2
    obj.Expanding = 7
    obj.Fixed = 0
    obj.Frame = 16
    ...
    

    ...但这些在运行选项卡式与 MDI 模式时也不会改变。

    那么,也许这是预期的行为?如果是这样,那意味着您必须找到类似“单独”选项卡显示小部件的东西;以编程方式添加几个 QMdiAreas;在开始时隐藏所有这些,但默认的除外;然后绑定单击各个选项卡以显示“他们的”QMdiArea 并隐藏其他选项卡(但不用说,我还没有测试过)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-15
      • 2019-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多