QDockWidget Draggable Tabs - PullRequest
       43

QDockWidget Draggable Tabs

19 голосов
/ 24 февраля 2011

Я использую QDockWidgets и размещаю два из них на левой стороне моего приложения, чтобы можно было использовать вкладки для выбора между ними.Однако поведение Qt по умолчанию выглядит ужасно и не интуитивно понятно.Вместо того, чтобы перетаскивать вкладки для перемещения виджетов, он размещает другую панель под выбранной вкладкой (с тем же именем), которую нужно перетаскивать.Как пользователю, было бы трудно понять это.

enter image description here

(Мои QDockWidgets - "Атрибуты" и "Библиотека")

Есть ли способизбавиться от этой второй панели и сделать так, чтобы я мог перемещать свои QDockWidgets, перетаскивая сами вкладки?

Ответы [ 6 ]

6 голосов
/ 21 июня 2012

Если вы добавляете 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);
3 голосов
/ 16 февраля 2012

Насколько я вижу из QDockWidget::mousePressEvent реализации в src/gui/widgets/qdockwidget.cpp перетаскивание доки с помощью вкладок - это НЕ возможно:

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 голосов
/ 27 октября 2011

Я думаю, Том был не слишком далеко от решения:

Вы можете установить свой собственный виджет в качестве строки заголовка:

myDockingWidget->setTitleBarWidget(myTitleBar)

Если вы создаете этот виджет, чтобы не отображатьзаголовок окна док-станции, у вас есть.Посредством сигнала QDockWidget::topLevelChanged ваш док-виджет может даже стать информированным, когда он станет плавающим, и вы сможете снова включить заголовок в myTitleBar.

1 голос
/ 24 февраля 2011

вы пробовали:

myDockingWidget->setTitleBarWidget(0)

edit:

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

где 'this' - QMainWindow

это удалитв строке заголовка, хотя я не уверен, как сделать перетаскивание QDockWidget из вкладок

0 голосов
/ 12 сентября 2012

Я также думаю, что setTitleBarWidget() действительно добивается цели.Я помню, как он использовался для аналогичной цели в исходном коде музыкального проигрывателя Amarok .Amarok имеет QMainWindow, которое содержит только виджеты для док-станции.Возможно, вы захотите взглянуть на исходный код.

0 голосов
/ 09 августа 2011

Похоже, вы установили положение вкладки дока сверху.По умолчанию он находится внизу.Тогда визуально не так страшно иметь текст вкладки рядом с текстом строки заголовка.

Я не думаю, что есть какой-либо способ сделать то, что вы предлагаете в Qt (исключите строку заголовка QDockWidget)и перетащите из вкладки), по крайней мере, не со стандартными виджетами.Возможно, вы могли бы написать много пользовательского кода, чтобы это произошло, но это, вероятно, не стоит.

Вместо этого я бы предложил переместить вкладки вниз (см. QMainWindow::setTabPosition) или, возможно, одну изстороны.

...