Прокрутка подокна Python PyQt/PySide QMdiArea не работает в TabbedView

У меня есть простой пример настройки с использованием дизайнера PyQt. См. Ниже. У меня есть mdiarea, в котором я добавляю форму как подокно. Я сделал форму немного длиннее, чем главное окно, чтобы увидеть, появляется ли полоса прокрутки для дочернего подокна.

ПРОБЛЕМА: если я установлю для mdiarea значение setViewMode(QtGui.QMdiArea.TabbedView), полосы прокрутки перестанут работать и исчезнут. Howeevr Если я не использую TabbedView, полосы прокрутки работают нормально. Кто-нибудь может сказать мне, что не так? Мне нужен TabbedView mdiarea с работающими полосами прокрутки.

Я использую Python 2.7, PyQT 4.8.4/PySide 1.2.1 на win7.

Пример кода 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_())

person django    schedule 23.08.2013    source источник


Ответы (1)


Просто хотел сказать спасибо за код в OP - искал простой пример MDI в PyQT, и ваш мне очень помог! У меня точно нет ответа, но это то, что я пока могу отметить: у меня есть Python 2.7, PyQT 4.8.3, и, просто закомментировав строки setTabsClosable и setTabsMovable, я мог бы показать ваш пример следующим образом:

qt1qt2

Скачал designer-qt4 и посмотрел там про QMdiArea, там вроде ничего не называется TabbedView. Итак, я нашел это:

QtWidgets 5.0: класс QMdiArea | Документация | Проект Qt

enum ViewMode { SubWindowView, TabbedView }
Это перечисление описывает режим просмотра области; т. е. как будут отображаться подокна.
SubWindowView 0 Отображать подокна с оконными рамами (по умолчанию).
TabbedView 1 Отображать подокна с вкладками на панели вкладок.
documentMode: Это свойство определяет, панель вкладок установлена ​​в режим документа в режиме просмотра с вкладками.

Как я прочитал это: либо вы можете отображать подокна в стиле MDI (чтобы они могли быть больше, чем окно, с полосами прокрутки), или подокна становятся вкладками в представлении с вкладками - и здесь размер подокна больше не имеет значения, поэтому оно расширяется, чтобы занять доступную область вкладок. Кроме того, в вашем коде self.ui.mdiArea.documentMode() возвращает False в обоих случаях.

Я также добавил этот фрагмент в конце вашего MyApp.Add_Subwindow():

    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 и скрыть остальные (но, разумеется, я не проверял это).

person sdaau    schedule 11.11.2013