我有一个MdiChilds应用程序,它应该包含多个QDockWidgets。但是,我在拆分/标签小部件以使它们生成所需的默认布局时遇到了问题。我基本上想要这样的布局:

小部件4是最后创建的,需要放在表格化的小部件2& 3旁边。但是,插入它会导致自身和另一个小部件丢失:

下面是生成第二个屏幕截图的代码:
在主窗口(或mdi childs )的构造函数中,我执行以下操作:
QDockWidgetTest::QDockWidgetTest(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
setCentralWidget(0); // only QDockWidgets
QWidget* testWidget1 = new TestWidget("1", QColor("red"));
QWidget* testWidget2 = new TestWidget("2", QColor("green"));
QWidget* testWidget3 = new TestWidget("3", QColor("blue"));
QWidget* testWidget4 = new TestWidget("4", QColor("yellow"));
DockWidgetWrapper* testQWidget1 = new DockWidgetWrapper(testWidget1, "Test Widget 1", "TestWidget1");
DockWidgetWrapper* testQWidget2 = new DockWidgetWrapper(testWidget2, "Test Widget 2", "TestWidget2");
DockWidgetWrapper* testQWidget3 = new DockWidgetWrapper(testWidget3, "Test Widget 3", "TestWidget3");
DockWidgetWrapper* testQWidget4 = new DockWidgetWrapper(testWidget4, "Test Widget 4", "TestWidget4");
addDockWidget(Qt::LeftDockWidgetArea, testQWidget1);
splitDockWidget(testQWidget1, testQWidget2, Qt::Vertical);
tabifyDockWidget(testQWidget2, testQWidget3);
splitDockWidget(testQWidget3, testQWidget4, Qt::Horizontal);
}其中,TestWidget被定义为一个简单的Widget,它只是在给定的颜色中绘制自己,在中间画标题:
#include <QWidget>
#include <QPainter>
#include <QPaintEvent>
#include <QFontMetrics>
class TestWidget: public QWidget
{
private:
QString m_content;
QColor m_fillColor;
public:
TestWidget(QString content, QColor color):
m_content(content),
m_fillColor(color)
{
m_fillColor.setAlpha(50);
}
protected:
void paintEvent(QPaintEvent* e)
{
QPainter p(this);
QFontMetrics fm(p.font());
QRect g(geometry());
p.fillRect(g, m_fillColor);
p.drawText(g.width()/2 - fm.width(m_content), g.height()/2 + fm.height(), m_content);
}
};对于任何一个DockWidgetWrapper,QDockWidget都是一个简单的包装器:
#include <QDockWidget>
#include <QVBoxLayout>
class DockWidgetWrapper: public QDockWidget
{
public:
DockWidgetWrapper(QWidget* widget, QString const & windowTitle, QString const & objectName)
{
setWindowTitle(windowTitle);
setFeatures(DockWidgetClosable | DockWidgetMovable | DockWidgetFloatable);
setWidget(widget);
setObjectName(objectName);
}
};小部件3和4在上一次splitDockWidget调用之后完全消失了,因此在表化小部件上调用splitDockWidget会使待插入的小部件和表化的小部件消失。如果我在QDockWidget头上打开上下文菜单,并使Widget2在其中消失,这个应用程序看起来就更奇怪了:

因此,有一个小部件3和4应该位于的空白区域(根据上下文菜单,Qt似乎还在显示它们的印象中!)只有在同时禁用这两种功能时,Widget1下面的空区域才会消失。
如果我先分裂然后制表,那就好了。问题是,我想在软件的一般部分中进行制表,然后在加载它的一个专门部分时进行拆分。所以对我来说,重新安排这两件事并不是一种选择。在文件中我只能在上面找到以下内容:
注意:如果第一个当前在一个选项卡停靠区域,第二个将作为一个新的选项卡添加,而不是作为第一个的邻居。这是因为单个选项卡只能包含一个坞小部件。
这绝对不是发生的事。此外,这种描述还存在一些有待改进的地方:在我的示例中,这意味着一旦我有了选项卡小部件2和3,就没有办法(以编程的方式)将小部件4放在这两个部件的右边,或者有其他方法实现这一点吗?
对我来说,QT4.8和5.3都会出现这个问题。我想这可能是Qt中的一个bug?这是一个已知的错误(到目前为止,我的搜索结果是空的)吗?或者,对此还有其他合理的解释,或者是“找回”两个丢失的小部件的方法吗?
发布于 2015-04-02 17:09:09
我相信你对错误的评估是正确的,所以这是一个可能的解决办法。
我发现,我可以通过显式地向表单中添加停靠小部件并指定其停靠区域,然后进行制表,从而获得所需的结果。我知道你想要相反的顺序,但至少这能消除那些奇怪的东西。
首先,确保通过设计器或类似于编程的方式启用了停靠嵌套和选项卡(您可以选择在这里包括动画):
setDockOptions(DockOption::AllowNestedDocks | DockOption::AllowTabbedDocks);然后显式地添加每个坞。你只加了一个。
addDockWidget(Qt::TopDockWidgetArea, testQWidget1);
addDockWidget(Qt::LeftDockWidgetArea, testQWidget2);
addDockWidget(Qt::LeftDockWidgetArea, testQWidget3);
addDockWidget(Qt::RightDockWidgetArea, testQWidget4);通过将最后一个设置为:
Qt::RightDockWidgetArea它似乎把它定位在你想要的地方。然后打电话:
tabifyDockWidget(testQWidget2, testQWidget3);如果您希望再次调用addDockWidget(),您以后可以通过编程将停靠移到新的位置。Qt非常聪明,可以意识到您正在重新添加一个现有的Qt,所以它不会复制它。
在运行这个测试代码时,我唯一的问题是,顶部的端口看起来很大,占用了大部分空间。我相信,一旦您在每个控件中添加控件,它们就会适当地调整大小。
我很想知道您的解决方案是什么,因为我即将开始一些与码头相关的工作。
希望这能有所帮助。
这是我在潜伏多年后的第一次回答,所以请放心吧。
https://stackoverflow.com/questions/28151738
复制相似问题