未停靠的QDockWidget中的最大化和最小化按钮

5

我一直在尝试像对待QDialog一样为未停靠的QDockWidget窗口添加按钮,但是一直没有成功,具体情况如下:

QDockWidget* dw = new QDockWidget(QString("Stream %1").arg(i + 1), this); 
dw->setWindowFlags((dw->windowFlags() | Qt::WindowMaximizeButtonHint |
    Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint));

当我拆下它们时,它们仍然只有 [X] 关闭按钮。

我错过了什么吗?

开发环境信息: Windows 10 x64, Visual Studio 2015, Qt 5.7.1, C++

2个回答

13

我找到了如何做到这一点。您需要连接到 QDockWidget toplevelChanged(bool) 信号。

connect(ui.dockWidget, SIGNAL(topLevelChanged(bool)), this, SLOT(dockWidget_topLevelChanged(bool)));

然后您需要检查它是否浮动并设置窗口提示。

void MyClass::dockWidget_topLevelChanged(bool)
{
    QDockWidget* dw = static_cast<QDockWidget*>(QObject::sender());
    if (dw->isFloating())
    {
        dw->setWindowFlags(Qt::CustomizeWindowHint |
            Qt::Window | Qt::WindowMinimizeButtonHint |
            Qt::WindowMaximizeButtonHint |
            Qt::WindowCloseButtonHint);
        dw->show();
    }
}

3
以下是如何在 Windows 任务栏中单独显示此 QDockWidget 的步骤。https://stackoverflow.com/a/54459140/2721136 - KungPhoo

3
很抱歉,您不能以这种方式操作,因为 QDockWidget 的外观和感觉基本上是硬编码在您的应用程序中使用的 QStyle 中的,如文档所述(此处 在“外观”部分)。 基本上,QDockWidget 是一个 无边框 窗口,标题栏及其结构(标题、按钮等)只是使用样式绘制而已。
要克服这个问题,您可以使用 QProxyStyle 来绘制最小化和最大化按钮,但这些不会是“真正”的按钮,而只是它们的像素图。 因此,您仍然需要进行一些调整来处理对这些虚拟按钮的点击(例如,在标题栏上捕获单击事件,并确定它是否发生在其中一个这些按钮内)。
另一个可能的解决方案是子类化 QDockWidget 并在那里实现所有绘画和点击事件处理。 请注意,如果您想支持多个平台,则可能需要使用 QStyle::drawControl() 来绘制额外的按钮,而不是自己绘制一切(例如,绘制像素图)。
我希望这能对你有所帮助。祝你的项目好运。

这实际上是一个不错的解决方案,对于按钮,我可以使用MousePressEvent并从光标覆盖“按钮”的.rect(),然后查看是否被点击。这与我最终所做的类似,但我最终是通过子类化QTabWidgets来重新实现单击和移动事件,并取消父子关系并重新设置它们的父子关系。在视觉上,它们更适合我所需的(因为我将中央布局的最大大小设置为(0,0)以使QDockWidgets不作为停靠窗口,而像主要小部件)。 - Petar Petrov
我找到了一个解决方案,连接到toplevelchanged信号。 我很快会发布解决方案。 - Petar Petrov

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