Подтвердить что ты не робот

Перетаскиваемые вкладки QDockWidget

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

enter image description here

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

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

4b9b3361

Ответ 1

Если вы добавляете 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);

Ответ 2

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

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

myDockingWidget->setTitleBarWidget(myTitleBar)

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

Ответ 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 перед тем, как разрешить расстыковку, - это то, что событие нажатия мыши появилось из строки заголовка или нет.

Ответ 4

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

myDockingWidget->setTitleBarWidget(0)

изменить

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

где 'this' - QMainWindow

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

Ответ 5

Похоже, вы установили, что позиция вкладки док-станции находится сверху. По умолчанию это будет внизу. Затем это не так визуально, чтобы иметь текст вкладки прямо рядом с текстом строки заголовка.

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

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

Ответ 6

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