【问题标题】:How to allow interactive resizing of floating Qt5 dock widget如何允许浮动 Qt5 停靠小部件的交互式调整大小
【发布时间】: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 首先启用此功能?

【问题讨论】:

    标签: qt qt5


    【解决方案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 标志已经为我设置为浮动 QDockWidgets(Debian sid 上的 PySide2 5.11.2,使用 KDE),但是清除 Qt::FramelessWindowHint 标志可以获得正常的窗口边框出现。也没有必要拨打QWidget::show()。 (续)
    • 确实有一个小问题,因为 QDockWidget 在最初被取消停靠时会消失,直到窗口被放下,但我不确定这不是 Linux 的事情。清除Qt::BypassWindowManagerHint 并调用QWidget::show() 会在最初取消停靠时显示窗口,但随后在调整大小时窗口往往会消失。 (续)
    • Qt Designer 似乎有带有适当边框的 QDockWidgets,并且没有额外的窗口标题来指示已清除的 Qt::FramelessWindowHint 标志,但我不确定他们是如何实现的。
    猜你喜欢
    • 2022-08-17
    • 2014-08-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2016-06-01
    • 2016-08-18
    • 2021-03-31
    • 1970-01-01
    相关资源
    最近更新 更多