QDockWidget 可拖动选项卡

发布于 2024-10-18 15:31:56 字数 302 浏览 2 评论 0原文

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

在此处输入图像描述

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

有没有办法摆脱第二个栏并使其可以通过拖动选项卡本身来移动我的 QDockWidgets?

I am using QDockWidgets and placing two of them on the left side of my application so that tabs can be used to select between them. However, Qt's default behavior for this looks horrible and is unintuitive. Instead of being able to drag the tabs to move the widgets, it places another bar below the selected tab (with the same name) that must be dragged instead. As a user, it would be hard to figure this out.

enter image description here

(My QDockWidgets are "Attributes" and "Library")

Is there a way to get rid of this second bar and make it so I can move my QDockWidgets by dragging the tabs themselves?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

人间☆小暴躁 2024-10-25 15:31:56

如果您要将 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);

If you are adding QTabWidgets to a main window derived from QMainWindow, you can try tabifyDockWidget.
It tabifies two QDockWidgets just like you wanted and of course you are able to drag them.

dockWidget1 = new QDockWidget("Tab1") ;
dockWidget2 = new QDockWidget("Tab2") ;
this->addDockWidget(Qt::LeftDockWidgetArea ,  dockWidget1 );
this->addDockWidget(Qt::LeftDockWidgetArea ,  dockWidget2 );
this->tabifyDockWidget(dockWidget1,dockWidget2);
岛徒 2024-10-25 15:31:56

我认为,Tom 距离解决方案并不遥远:

您可以将自己的小部件设置为标题栏:

myDockingWidget->setTitleBarWidget(myTitleBar)

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

I think, Tom was not too far away from a solution:

You can set your own Widget as title bar:

myDockingWidget->setTitleBarWidget(myTitleBar)

If you design this widget to not show the dock window title, you have it. Via the signal QDockWidget::topLevelChanged your docking widget can even become informed, when it gets floating, so you could then enable the title in myTitleBar again.

贱贱哒 2024-10-25 15:31:56

据我所知,从src/gui/widgets/qdockwidget.cpp中的QDockWidget::mousePressEvent实现来看,使用选项卡拖动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 在允许取消停靠之前检查的事情之一是鼠标按下事件是否来自标题栏。

As far as I can see from QDockWidget::mousePressEvent implementation in src/gui/widgets/qdockwidget.cpp dragging the dockwidgets using tabs is NOT possible:

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);
    ....

As you can see from the implementation one of the things that the QDockWidget checks before allowing undocking is whether the mouse press event has come from title bar or not.

始终不够爱げ你 2024-10-25 15:31:56

编辑:

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


也许你可以尝试这种奇怪的方法,即将停靠小部件区域中的 QWidget 移动到标题栏。

我修改了文件夹中的demo

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

来展示它是如何工作的:

在“void 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

演示:

拖动面板的边缘来移动,实际上,您可以拖动空白区域(没有子小部件区域)。该面板上的小部件仍然可以正常工作。

拖动要移动的面板边缘

Edited:

Please do not use this method. It introduces problems rather than soloves them.


Maybe you can try this wierd way, that is move the QWidget in the dock widget area to the title bar.

I modify the demo in folder

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

to show how it works:

In "void 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

The demo:

Drag the edge of the panel to move, actually you can drag the empty area (no child widget area). The widget on this panel still functional properly.

drag the edge of the panel to move

另类 2024-10-25 15:31:56

您是否尝试过:

myDockingWidget->setTitleBarWidget(0)

编辑:

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

其中“this”是一个 QMainWindow

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

have you tried:

myDockingWidget->setTitleBarWidget(0)

edit:

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

where 'this' is a QMainWindow

this will remove the title bar, though im not sure how to make the QDockWidget draggable from the tabs

孤千羽 2024-10-25 15:31:56

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

I also think that setTitleBarWidget() really does the trick. I remember seeing it being used for a similar purpose in the source code of the Amarok music player. Amarok has a QMainWindow which only contains dock widgets. You might want to have a look at the source code there.

指尖凝香 2024-10-25 15:31:56

您似乎已将停靠选项卡位置设置在顶部。默认情况下它位于底部。这样,将选项卡文本放在标题栏文本旁边就不会造成视觉上的不和谐。

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

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

It looks like you've set your dock tab position to be on the top. The default is for it to be on the bottom. Then it's not as visually jarring to have the tab text right next to the title bar text.

I don't think there's any way to do what you're proposing in Qt (eliminate the QDockWidget title bar and drag from the tab), at least not with the standard widgets. You could probably write a lot of custom code to make it happen, but that's probably not worth it.

Instead, I'd suggest moving the tabs to the bottom (see QMainWindow::setTabPosition) or possibly one of the sides.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文