21

我正在使用 QDockWidgets 并将其中两个放在我的应用程序的左侧,以便可以使用选项卡在它们之间进行选择。然而,Qt 的默认行为看起来很糟糕而且不直观。它不能拖动选项卡来移动小部件,而是在必须拖动的选定选项卡(具有相同名称)下方放置另一个栏。作为用户,很难弄清楚这一点。

在此处输入图像描述

(我的 QDockWidgets 是“属性”和“库”)

有没有办法摆脱第二个栏并制作它,以便我可以通过拖动标签本身来移动我的 QDockWidgets?

4

7 回答 7

6

如果你是添加QTabWidgets到一个主窗口派生的QMainWindow,你可以试试tabifyDockWidget。它QDockWidgets就像您想要的那样将两个标签化,当然您可以拖动它们。

dockWidget1 = new QDockWidget("Tab1") ;
dockWidget2 = new QDockWidget("Tab2") ;
this->addDockWidget(Qt::LeftDockWidgetArea ,  dockWidget1 );
this->addDockWidget(Qt::LeftDockWidgetArea ,  dockWidget2 );
this->tabifyDockWidget(dockWidget1,dockWidget2);
于 2012-06-21T15:53:20.387 回答
4

我认为,汤姆离解决方案并不远:

您可以将自己的 Widget 设置为标题栏:

myDockingWidget->setTitleBarWidget(myTitleBar)

如果您将此小部件设计为不显示停靠窗口标题,那么您拥有它。通过信号,QDockWidget::topLevelChanged您的停靠小部件甚至可以在浮动时收到通知,因此您可以再次启用标题myTitleBar

于 2011-10-27T10:47:58.283 回答
4

据我从QDockWidget::mousePressEvent实现中可以src/gui/widgets/qdockwidget.cpp看出,使用选项卡拖动dockwidgets是不可能的:

QDockWidgetLayout *dwLayout
    = qobject_cast<QDockWidgetLayout*>(layout);

if (!dwLayout->nativeWindowDeco()) {
    QRect titleArea = dwLayout->titleArea();

    if (event->button() != Qt::LeftButton ||
        !titleArea.contains(event->pos()) ||
        // check if the tool window is movable... do nothing if it
        // is not (but allow moving if the window is floating)
        (!hasFeature(this, QDockWidget::DockWidgetMovable) && !q->isFloating()) ||
        qobject_cast<QMainWindow*>(parent) == 0 ||
        isAnimating() || state != 0) {
        return false;
    }

    initDrag(event->pos(), false);
    ....

正如您从实现中看到的那样,QDockWidget在允许取消停靠之前检查的一件事是鼠标按下事件是否来自标题栏。

于 2012-02-16T16:01:59.027 回答
1

你有没有尝试过:

myDockingWidget->setTitleBarWidget(0)

编辑:

    QWidget* titleWidget = new QWidget(this);
    mUi.dockWidget->setTitleBarWidget(titleWidget);

其中“this”是一个 QMainWindow

这将删除标题栏,尽管我不确定如何使 QDockWidget 可以从选项卡中拖动

于 2011-02-24T12:57:42.767 回答
1

编辑:

请不要使用这种方法。它引入问题而不是解决问题。


或许你可以试试这个比较奇葩的方法,就是将dock widget区域中的QWidget移动到标题栏。

我修改文件夹中的演示

C:\Qt\Qt5.12.9\Examples\Qt-5.12.9\widgets\mainwindows\dockwidgets

展示它是如何工作的:

在“无效 MainWindow::createDockWindows()”中

QDockWidget *dock = new QDockWidget(tr("Customers"), this);
dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);

//make a panel to hold your widgets
QWidget *p = new QWidget(dock);
QVBoxLayout *l = new QVBoxLayout(p);
p->setLayout(l);
customerList = new QListWidget(p);
l->addWidget(customerList);

customerList->addItems(QStringList()
        << "John Doe, Harmony Enterprises, 12 Lakeside, Ambleton"
        << "Jane Doe, Memorabilia, 23 Watersedge, Beaton"
        << "Tammy Shea, Tiblanka, 38 Sea Views, Carlton"
        << "Tim Sheen, Caraba Gifts, 48 Ocean Way, Deal"
        << "Sol Harvey, Chicos Coffee, 53 New Springs, Eccleston"
        << "Sally Hobart, Tiroli Tea, 67 Long River, Fedula");

dock->setWidget(new QWidget());//hide the real dock area
dock->setTitleBarWidget(p); //use the titlebar erea to show the content

演示:

拖动面板边缘移动,实际上可以拖动空白区域(无子窗口小部件区域)。此面板上的小部件仍然可以正常工作。

拖动面板边缘移动

于 2020-09-17T09:36:45.863 回答
0

我也认为这setTitleBarWidget()确实有效。我记得在Amarok 音乐播放器的源代码中看到它被用于类似目的。Amarok 有一个 QMainWindow,它只包含停靠小部件。你可能想看看那里的源代码。

于 2012-09-12T09:21:35.670 回答
-1

看起来您已将停靠选项卡位置设置在顶部。默认是在底部。然后,将标签文本放在标题栏文本旁边就不会在视觉上不和谐。

我认为没有任何方法可以执行您在 Qt 中提出的建议(消除QDockWidget标题栏并从选项卡中拖动),至少不能使用标准小部件。您可能可以编写很多自定义代码来实现它,但这可能不值得。

相反,我建议将选项卡移到底部(请参阅 参考资料QMainWindow::setTabPosition)或可能的一侧。

于 2011-08-08T21:59:20.297 回答