【问题标题】:How to avoid ugly overlap with too many dockwidgets in QMainWindow?如何避免在 QMainWindow 中与太多的停靠小部件发生丑陋的重叠?
【发布时间】:2012-07-17 09:22:29
【问题描述】:

在我们的应用程序中,我们有可变数量的停靠小部件,因为其中一些是由在运行时加载的插件添加的。并非所有的dockwidgets都必须同时可见。这在很大程度上取决于用户正在做什么以及哪些插件处于活动状态。

但是,如果使用addDockWidget(...) 以编程方式添加了太多的dockwidgets,它们就会开始相互重叠(不是在选项卡方面,而是在一个被绘制在不同区域的内容方面,这显然看起来破碎的)。

用户可以将dockwidgets移动到仍然有空间的dockarea,但是布局/主窗口成功地防止(未选项卡)重新添加到“拥挤”的dockarea。

我们确实允许选项卡式停靠以允许用户安排所需的停靠小部件,但我们不想启用QMainWindow::ForceTabbedDocks,因为这会过多地限制同时可见的停靠小部件的数量(每个停靠区域一个)。

我怎样才能防止这种情况或更好地控制如何添加dockwidgets?

【问题讨论】:

    标签: c++ qt qdockwidget


    【解决方案1】:

    不直接回答您的问题,但实际上忘记 Qt 并真正考虑整个交互应该如何工作可能是值得的。用户的期望是什么?如果 10 个不同的插件激活,实际会发生什么?它们应该停靠还是浮动,或者它们应该成为具有初始状态的可固定停靠窗口,作为 MainWindow 边缘上的一个小按钮?我认为,一旦您完成了基础工作并提出了用户界面模型,您就可以开始查看 Qt 并确定 Qt 是否提供了开发该界面的直接方法,如果没有,您需要开发哪些附加组件让该界面正常工作。

    根据我自己的经验,我很久以前就在 MFC 中开发过类似的界面。我们这样做的方式是,一些停靠的窗户被认为是必须拥有的,它们会像停靠一样出现。然后有一组不需要总是可见但应该快速可用的窗口,它们的初始状态是隐藏的可固定停靠窗口,这意味着它们作为 MainWindow 边缘的按钮出现。最后还有一个用户并不总是需要的第三组,可以从 File->View Menu 中调用。一旦用户使其可见,用户通常会将其分配给前两个组之一或使其保持浮动。整个配置保存在配置文件中,并且从那里开始,每当插件加载/变为活动时,使用关联停靠窗口的最后使用状态。它虽然涉及相当多的额外工作,但最终的结果是让所有用户都满意。

    【讨论】:

    • 谢谢。我想这是一个合理的建议。这可能是一个很好的例子,当迷失在技术细节中时,退后一步重新考虑整体设计和大局总是一个好主意。
    【解决方案2】:

    你试过setDockOptions(QMainWindow::AllowNestedDocks)吗?我现在无法测试它,但它可能会有所帮助。 默认情况下,QMainWindow::dockOptions 设置为 AnimatedDocks | AllowTabbedDocks,因此您需要类似

    setDockOptions(QMainWindow::AllowNestedDocks | QMainWindow::AnimatedDocks | QMainWindow::AllowTabbedDocks)
    

    编辑: 如果你有太多问题,你可能会以错误的方式解决这个问题。您可能想尝试将 QMdiArea 与 QMdiWindow 一起使用,而不是使用扩展坞。这可能不适用于您的程序,但需要考虑一下。

    【讨论】:

    • 我会试试这个,虽然我不确定我是否喜欢AllowNestedDocks。就像现在一样,当您只想移动浮动小部件时,有时停靠小部件开始 捕捉 到不同的区域已经很烦人了。启用嵌套甚至会增加可能的停靠区域的数量,不是吗?
    • 会的。 qt 文档指出它对许多码头都有好处,但它可能很烦人。
    • 情况更糟。首先,它不起作用。使用单一“级别”的dockwidgets,它和以前一样。但是如果我嵌套到彼此相邻的dockwidgets,然后以编程方式将另一个dockwidget添加到该区域,它只会重叠both嵌套的dockwidgets:/
    【解决方案3】:

    这是我尝试过的解决方案:

    1. 我在 QTCreator 中创建了一个空项目,其中包含一个窗口、一个标有“New Dock”的简约菜单和一个名为 dockWidget 的 DockWidget

    2. 这是我的菜单项的 triggered() 处理程序:

        void MainWindow::on_actionNew_Dock_triggered()
       {    
           QDockWidget* w = new QDockWidget("Demo", ui->dockWidget);
           this->addDockWidget(Qt::LeftDockWidgetArea,w);
           this->tabifyDockWidget(ui->dockWidget,w);
       }
      

    tabifyDockWidget(QDockWidget* first, QDockWidget* second) 是一个 QMainWindow 方法,它将第二个 dockwidget 堆叠在第一个之上。希望对你有帮助...

    【讨论】:

    • 但是,我需要先检查那一侧是否已经有一个停靠小部件,如果有多个,请决定要标记哪个。但即使这样也不能解决我猜的问题:假设LeftDockWidgetArea 中有两个dockwidgets。 W.r.t 它们的最小尺寸,它们占据了所有可用空间。一个很小,一个很大。我添加了一个相当大的dockwidget。如果我现在选择用我的新dockwidget 标记的小一个,恐怕会遇到完全相同的问题(两个并排的dockwidget,都太大了,所以Qt 会覆盖minimumSize 并导致丑陋的重叠。
    • 或者我错过了什么?也许我们必须重新定义何时、如何以及在何处可以添加哪些dockwidgets的整个“过程”......
    • 您可以在插件级别实现选项卡/停靠策略。不过,我假设您的插件派生自 QWidget 并设置为 QDockWindow 的主要小部件。如果是这种情况,共同的插件祖先可以设计一个基本的停靠/定位策略,可以由他们的后代修改。
    • 更多相关信息:Visual Studio 2010 的每个窗格(监视、编译器消息、搜索/替换等)几乎可以停靠在任何地方,但根据它们的布局,它们有一个首选默认值:监视通常出现在底部,类层次结构在左侧或右侧,搜索/替换为独立窗口......但是,您可以将它们停靠在其他任何地方。我认为您的插件应该遵循类似的路径。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-23
    • 2015-04-15
    • 2020-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多