只有 QDockWidgets 而没有中心窗口的 QMainWindow

21
我们有一个窗口,其中包含几个 QDockWidget 组件。理想情况下,我们希望所有组件都可以停靠,但可能始终会有一个组件是可见的。因此,我们将其设置为中心组件。
然而,这不允许我们创建一个包含此中心部件的可停靠小部件的选项卡堆栈(例如通过调用 tabifyDockWidget 创建)。因此,我们尝试创建一个没有中心小部件但有多个 QDockWidget 的 UI。
我在 QDockWidget 或 QMainWindow 手册中找不到任何迹象表明这不是允许的情况。我们尽可能在 Qt Designer 中创建,但似乎需要一个中心小部件-因为在手动编辑 XML 后显示并崩溃。
问题是:只有 QDockWidget 而没有中心小部件的 QMainWindow 是否合法?Qt Designer 只是因为软件漏洞而崩溃,还是告诉我这是个坏主意,我需要停止这样做?
7个回答

15

Qt的文档中提到:

注意:不支持创建没有中央窗口部件的主窗口。即使只是一个占位符,您也必须有一个中央窗口部件。

因此,您可以隐藏空的中央窗口部件:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->centralWidget->hide();
}

5
中央小部件可以只是另一个可停靠的小部件吗? - Troyseph

10

如果我在"ui->setupUi(this)"生成的那行代码后面输入这个,它对我有效。

MainWindow::setCentralWidget(NULL);

我不知道它是否“合法”,但我知道它对我很有效。

(我知道这是一个旧问题,但仍然有效 :))


它可以工作!但要注意,我遇到了一些奇怪的错误:如果我说右下角被底部停靠栏使用,并且我添加了一些底部停靠栏,那么有时在右侧停靠栏和底部停靠栏之间调整大小将不再起作用。然而,在这种特殊情况下,底部停靠栏==右侧停靠栏,如果我使用右侧停靠栏而不是底部停靠栏,则调整大小会起作用。因此,行为会在没有中央小部件的情况下发生变化。顺便说一句,如果我添加一个中央小部件但将其“隐藏”,则会出现相同的效果。 - IceFire

3
胡说八道!我有一个只有QDockWidgets而没有中央小部件的完全功能的QMainWindow。我不知道它是否“合法”,但如果您在QtDesigner之外创建它,这绝对是可能的,而这也很容易。

示例

from PyQt4 import QtCore, QtGui

class Window(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.setWindowTitle('Dock Widgets')
        self.setTabPosition( QtCore.Qt.TopDockWidgetArea , QtGui.QTabWidget.North )
        self.setDockOptions( QtGui.QMainWindow.ForceTabbedDocks )

        self.dockList = []
        for dockName in 'First Second Third Fourth'.split():
            dock = QtGui.QDockWidget(dockName)
            dock.setWidget(QtGui.QListWidget())
            dock.setAllowedAreas(QtCore.Qt.TopDockWidgetArea)
            self.addDockWidget(QtCore.Qt.TopDockWidgetArea, dock)

            self.dockList.append( dock )


        if len(self.dockList) > 1:
            for index in range(0, len(self.dockList) - 1):
                self.tabifyDockWidget(self.dockList[index],self.dockList[index + 1])



if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.show()
    app.exec_()

1
我在使用pyside (python的QT)时遇到了这个问题。 我只需要dock,因此我必须创建一个假小部件(即标签)作为中心。 但是,一旦我隐藏它,dock就无法自由调整大小。 如果我将None / null作为中央小部件,则会发生相同的情况。
在互联网上搜索很久都没有结果后,我发现问题出在dock位置的初始设置(顶部/底部/左侧/右侧)。 如果我将它们全部放在同一位置(即顶部),并让用户进行组织,问题就不会出现。 然后我尝试仅使用顶部和底部位置(因为我可以按照所需方式组织dock而不使用侧面位置(顶部两个,底部一个)。 令我惊讶的是,这种安排最终解决了问题。

0

有一个解决方案! 虽然这仍然是一种hack方法,但可以按照您想要的最佳方式工作。

对于Python

window.setCentralWidget(None)
window.setDockNestingEnabled(True)

针对C++

window->setCentralWidget(NULL)
window->setDockNestingEnabled(true)

0

我也遇到了同样的问题,希望已经有一些好的解决方案。

看起来并没有,所以最终我想我会使用MdiArea。

也许你也可以考虑一下?它的工作方式不同,但也许足够好 :)


我做了。它们只是权宜之计。你仍然无法拥有可停靠的中央小部件。你可以使用其中一个停靠站作为中央,但这会导致你失去这个停靠站(例如,如果你使用顶部停靠站作为中央小部件,你就不能在其上停靠任何东西)。 - Michał Walenciak
它们是非常有效的解决方法。人们无法“检测”出有一个中央小部件与这个解决方法。 - dom0
如果我理解你的意思正确,你想说无法找出是否有中央小部件?这很简单。 - Michał Walenciak
1
不是从用户的角度来看。此外,我从语义学的角度来看,从未完全理解那些想要将码头作为中央小部件的人。 (我非常理解那些只想要由一些码头组成的窗口的人,并且我也使用过它)。 - dom0
即使从用户的角度来看,中央小部件也不允许将任何可停靠小部件放置在其上并且会逃跑。此外,您也无法移动中央小部件。 - Michał Walenciak
显示剩余2条评论

0
我将在此处发布基于threadsplitDockWidget的解决方案,因为这个12年前的问题仍然是搜索该问题时排名靠前的结果之一。 避免调整大小时出现奇怪行为的关键是只使用单个dock区域。使用splitDockWidget可以创建任何所需的dock布局。
import sys
from PyQt6.QtWidgets import QApplication,QMainWindow,QDockWidget
from PyQt6.QtCore import Qt

class Foo(QMainWindow):

    def __init__(self):
        super().__init__()
        self.resize(500, 500)         
        
        td = QDockWidget('topdock')
        ld = QDockWidget('leftdock')
        rd = QDockWidget('rightdock')
        rd2 = QDockWidget('rightdock2')
        bd = QDockWidget('bottomdock')            
        self.addDockWidget(Qt.DockWidgetArea.TopDockWidgetArea,td)
        self.splitDockWidget(td,ld,Qt.Orientation.Vertical)
        self.splitDockWidget(ld,bd,Qt.Orientation.Vertical)
        self.splitDockWidget(ld,rd,Qt.Orientation.Horizontal)   
        self.splitDockWidget(rd,rd2,Qt.Orientation.Vertical)   
            
if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainWindow = Foo()
    mainWindow.show()
    sys.exit(app.exec())

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接