我正在使用 QDockWidgets 并将其中两个放在我的应用程序的左侧,以便可以使用选项卡在它们之间进行选择。然而,Qt 的默认行为看起来很糟糕而且不直观。它不能拖动选项卡来移动小部件,而是在必须拖动的选定选项卡(具有相同名称)下方放置另一个栏。作为用户,很难弄清楚这一点。
(我的 QDockWidgets 是“属性”和“库”)
有没有办法摆脱第二个栏并制作它,以便我可以通过拖动标签本身来移动我的 QDockWidgets?
我正在使用 QDockWidgets 并将其中两个放在我的应用程序的左侧,以便可以使用选项卡在它们之间进行选择。然而,Qt 的默认行为看起来很糟糕而且不直观。它不能拖动选项卡来移动小部件,而是在必须拖动的选定选项卡(具有相同名称)下方放置另一个栏。作为用户,很难弄清楚这一点。
(我的 QDockWidgets 是“属性”和“库”)
有没有办法摆脱第二个栏并制作它,以便我可以通过拖动标签本身来移动我的 QDockWidgets?
如果你是添加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);
我认为,汤姆离解决方案并不远:
您可以将自己的 Widget 设置为标题栏:
myDockingWidget->setTitleBarWidget(myTitleBar)
如果您将此小部件设计为不显示停靠窗口标题,那么您拥有它。通过信号,QDockWidget::topLevelChanged
您的停靠小部件甚至可以在浮动时收到通知,因此您可以再次启用标题myTitleBar
。
据我从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
在允许取消停靠之前检查的一件事是鼠标按下事件是否来自标题栏。
你有没有尝试过:
myDockingWidget->setTitleBarWidget(0)
编辑:
QWidget* titleWidget = new QWidget(this);
mUi.dockWidget->setTitleBarWidget(titleWidget);
其中“this”是一个 QMainWindow
这将删除标题栏,尽管我不确定如何使 QDockWidget 可以从选项卡中拖动
编辑:
请不要使用这种方法。它引入问题而不是解决问题。
或许你可以试试这个比较奇葩的方法,就是将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
演示:
拖动面板边缘移动,实际上可以拖动空白区域(无子窗口小部件区域)。此面板上的小部件仍然可以正常工作。
我也认为这setTitleBarWidget()
确实有效。我记得在Amarok 音乐播放器的源代码中看到它被用于类似目的。Amarok 有一个 QMainWindow,它只包含停靠小部件。你可能想看看那里的源代码。
看起来您已将停靠选项卡位置设置在顶部。默认是在底部。然后,将标签文本放在标题栏文本旁边就不会在视觉上不和谐。
我认为没有任何方法可以执行您在 Qt 中提出的建议(消除QDockWidget
标题栏并从选项卡中拖动),至少不能使用标准小部件。您可能可以编写很多自定义代码来实现它,但这可能不值得。
相反,我建议将选项卡移到底部(请参阅 参考资料QMainWindow::setTabPosition
)或可能的一侧。