QDockWidget可拖动选项卡

时间:2011-02-24 03:04:34

标签: c++ qt user-interface qt4 tabs

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

enter image description here

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

有没有办法摆脱这第二个栏并使其成为可以通过拖动标签本身来移动我的QDockWidgets?

7 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:3)

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

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

myDockingWidget->setTitleBarWidget(myTitleBar)

如果您将此窗口小部件设计为不显示停靠窗口标题,则可以使用它。通过信号QDockWidget::topLevelChanged,您的停靠小部件甚至可以在浮动时获得通知,这样您就可以再次在myTitleBar中启用标题。

答案 2 :(得分:3)

据我所知QDockWidget::mousePressEvent src/gui/widgets/qdockwidget.cpp使用标签拖动dockwidgets NOT 可能:

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在允许取消停靠之前检查的一件事是鼠标按下事件是否来自标题栏。

答案 3 :(得分:1)

你试过了吗?

myDockingWidget->setTitleBarWidget(0)

修改

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

其中'this'是QMainWindow

这将删除标题栏,但我不知道如何使QDockWidget可以从选项卡中拖动

答案 4 :(得分:1)

编辑:

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


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

我修改了文件夹中的演示

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

演示:

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

drag the edge of the panel to move

答案 5 :(得分:0)

看起来您已将停靠栏位置设置在顶部。默认是它在底部。然后,标题栏文本旁边的选项卡文本就不那么直观了。

我认为没有办法在Qt中做出你提出的建议(消除QDockWidget标题栏并从标签中拖动),至少不能使用标准小部件。你可能会编写很多自定义代码来实现它,但这可能不值得。

相反,我建议将标签移到底部(参见QMainWindow::setTabPosition)或可能是其中一侧。

答案 6 :(得分:0)

我也认为setTitleBarWidget()确实可以解决问题。我记得在Amarok music player的源代码中看到它被用于类似的目的。 Amarok有一个QMainWindow,它只包含dock小部件。您可能想查看那里的源代码。