如何允许浮动 Qt5 停靠小部件的交互式调整大小
Posted
技术标签:
【中文标题】如何允许浮动 Qt5 停靠小部件的交互式调整大小【英文标题】:How to allow interactive resizing of floating Qt5 dock widget 【发布时间】:2018-12-05 23:47:12 【问题描述】:我有以下 Qt5.11.0 代码来创建一个 qdockwidget。小部件的本质是允许用户在dockwidget 浮动时根据需要通过鼠标交互式地调整小部件的大小(下面的示例是人为设计的,但我相信可以说明问题)。
当我运行它并将dockwidget 浮动到它自己的***窗口中时,通过用户交互来调整dockwidget 的大小要么非常困难(Linux),要么不可能(OSX)。在 RHEL Linux 7.6 上,将鼠标悬停在浮动 Dockwidget 的右下角会产生一个“调整大小”光标,但是这种行为的热点最多只有一两个像素宽,这使得用户很难和令人沮丧调整浮动码头小部件的大小。在 OSX 10.13.6 上,我看不到任何通过鼠标交互来调整 dockwidget 大小的选项。
示例代码如下:
#include <QApplication>
#include <QMainWindow>
#include <QDockWidget>
#include <QTextEdit>
#include <QTextStream>
#include <QFile>
#include <QSizeGrip>
int
main( int argc, char *argv[] )
QApplication app( argc, argv );
QMainWindow* mw = new QMainWindow();
mw->setCentralWidget( new QWidget() );
QDockWidget* dockWidget = new QDockWidget( "Code viewer", mw );
mw->addDockWidget( Qt::LeftDockWidgetArea, dockWidget );
QTextEdit* textEdit = new QTextEdit( dockWidget );
dockWidget->setWidget( textEdit );
QFile file( "/etc/protocols" );
QString filler;
if( ! file.open( QIODevice::ReadOnly ) )
exit( -1 );
else
QTextStream in( &file );
while( ! in.atEnd() )
filler += in.readLine();
file.close();
textEdit->setText( filler );
mw->show();
return app.exec();
我已经尝试过 QSizeGrip() 并在网上搜索过,但到目前为止无济于事。
如何在 Linux 上使用 Qt 控制鼠标驱动的浮动码头小部件调整大小的热区大小,以及如何在 OSX 上使用 Qt 首先启用此功能?
【问题讨论】:
【参考方案1】:不幸的是,分离的 QDockWidget 的边框由窗口装饰器处理,因此您无法通过样式表或调整大小控制来更改它。 无论如何,您可以更改停靠小部件的窗口标志以强制窗口装饰器绘制常规边框。
在您的示例中,您可以这样做:
#include <QApplication>
#include <QMainWindow>
#include <QDockWidget>
#include <QTextEdit>
#include <QTextStream>
#include <QFile>
#include <QSizeGrip>
int main( int argc, char *argv[] )
QApplication app( argc, argv );
QMainWindow* mw = new QMainWindow();
mw->setCentralWidget( new QWidget() );
QDockWidget* dockWidget = new QDockWidget( "Code viewer", mw );
mw->addDockWidget( Qt::LeftDockWidgetArea, dockWidget );
// handle floating changes
QObject::connect(dockWidget, &QDockWidget::topLevelChanged, [dockWidget] (bool floating)
if (floating)
dockWidget->setWindowFlags(Qt::Window);
dockWidget->show();
);
QTextEdit* textEdit = new QTextEdit( dockWidget );
dockWidget->setWidget( textEdit );
QFile file( "/etc/protocols" );
QString filler;
if( ! file.open( QIODevice::ReadOnly ) )
exit( -1 );
else
QTextStream in( &file );
while( ! in.atEnd() )
filler += in.readLine();
file.close();
textEdit->setText( filler );
mw->show();
return app.exec();
Here您可以找到所有可用窗口标志的描述,以自定义您的小部件的外观。
【讨论】:
\@Gabriella,这对我在 Linux 和 OSX 上都非常有用——非常感谢简洁、快速和有效的答案。Qt::Window
标志已经为我设置为浮动 QDockWidget
s(Debian sid 上的 PySide2 5.11.2,使用 KDE),但是清除 Qt::FramelessWindowHint
标志可以获得正常的窗口边框出现。也没有必要拨打QWidget::show()
。 (续)
确实有一个小问题,因为 QDockWidget
在最初被取消停靠时会消失,直到窗口被放下,但我不确定这不是 Linux 的事情。清除Qt::BypassWindowManagerHint
并调用QWidget::show()
会在最初取消停靠时显示窗口,但随后在调整大小时窗口往往会消失。 (续)
Qt Designer 似乎有带有适当边框的 QDockWidgets,并且没有额外的窗口标题来指示已清除的 Qt::FramelessWindowHint
标志,但我不确定他们是如何实现的。以上是关于如何允许浮动 Qt5 停靠小部件的交互式调整大小的主要内容,如果未能解决你的问题,请参考以下文章