【问题标题】:How to resize a frameless widget in Qt如何在 Qt 中调整无框小部件的大小
【发布时间】:2013-09-13 16:02:04
【问题描述】:

我正在研究如何在 Qt 5.1 中调整无框小部件的大小。由于跨平台的考虑,Windows相关的代码将不合适。

现在我的方法是:当用户将鼠标悬停在窗口边缘(小部件)时,光标形状会发生变化以提示窗口可以在那时调整大小。单击然后拖动后,将显示一个橡皮筋来演示窗口将调整大小的矩形区域。一旦用户释放鼠标,橡皮筋就会消失,然后窗口会调整到所需的大小。我说清楚了吗?

由于Qt不能直接在屏幕上绘图,所以临时用一张全屏截图(放入QLabel)模拟实际屏幕,然后在全屏QLabel中构建橡皮筋。在用户看来,他们正在真正的窗口屏幕中拖动窗口。

我的问题是:用户单击主小部件后,虽然显示了全屏 QLabel,但橡皮筋拒绝出现。相反,只有先松开鼠标,然后再次单击拖动,橡皮筋才会出现。

虽然我向主小部件发送了一个“MouseButtonRelease”事件,并向标签发送了一个“MouseMove”事件,但它似乎不起作用。任何提示或建议将不胜感激,非常感谢!

(为简化代码,已删除所有其他额外代码)

mainwidget.h

    class MainWidget : public QWidget
    {
        Q_OBJECT

    public:
        MainWidget(QWidget *parent = 0);
        ~MainWidget();

    private:
        QScreen *screen;

        QLabel *fullScreenLabel;
        QPixmap fullScreenPixmap;
        QRubberBand *rubberBand;

    protected:
        virtual bool eventFilter(QObject *o, QEvent *e);

        void mousePressEvent(QMouseEvent *e);
    };

mainwidget.cpp

    MainWidget::MainWidget(QWidget *parent)
        : QWidget(parent)
    {
        this->setWindowFlags(Qt::FramelessWindowHint);
        screen = QGuiApplication::primaryScreen();
        rubberBand=NULL;

        fullScreenLabel=new QLabel();
        fullScreenLabel->installEventFilter(this);

        resize(600,450);
    }

    MainWidget::~MainWidget()
    {
        delete fullScreenLabel;
    }

    bool MainWidget::eventFilter(QObject *o, QEvent *e)
    {
        if(o!=fullScreenLabel)
            return QWidget::eventFilter(o,e);

        QMouseEvent *mouseEvent=static_cast<QMouseEvent*>(e);

        if(mouseEvent->type()==QEvent::MouseMove)
        {
            qDebug()<<"label mouse move: "<< mouseEvent->pos();
            if(!rubberBand)
            {
                rubberBand=new QRubberBand(QRubberBand::Rectangle,fullScreenLabel);
                rubberBand->setGeometry(QRect(this->pos(),QSize()));
                rubberBand->show();
            }

            rubberBand->setGeometry(QRect(this->pos(),mouseEvent->pos()).normalized());

            return true;
        }

        if((mouseEvent->button()==Qt::LeftButton)
                && (mouseEvent->type()==QEvent::MouseButtonRelease))
        {        
            if(rubberBand)
            {
                rubberBand->hide();
                delete rubberBand;
                rubberBand=NULL;
            }

            return true;
        }
        return false;
    }

    void MainWidget::mousePressEvent(QMouseEvent *e)
    {
        if(screen)
        {
            fullScreenPixmap=QPixmap();
            fullScreenPixmap=screen->grabWindow(0,0,0,-1,-1);
        }

        fullScreenLabel->setPixmap(fullScreenPixmap);
        fullScreenLabel->showFullScreen();

        QMouseEvent clickEvent(QEvent::MouseButtonRelease,
                               e->pos(),
                               Qt::LeftButton,
                               Qt::LeftButton,
                               Qt::NoModifier);
        qApp->sendEvent(this,&clickEvent);

        QMouseEvent moveEvent(QEvent::MouseMove,
                               this->pos(),
                               Qt::NoButton,
                               Qt::NoButton,
                               Qt::NoModifier);
        qApp->sendEvent(fullScreenLabel,&moveEvent);
    }

【问题讨论】:

    标签: qt resize


    【解决方案1】:

    您可以研究它是如何在 Qt 中完成的 - QSizeGrip。有same question

    【讨论】:

    • 非常感谢 Dmitry,我研究了代码 sn-p,它确实有效!我只是想知道是否还有其他选择,我的构想能否实现。
    • 刚才我在一个简单的演示中使用了QSizeGrip,它工作正常。但是现在当我把它放在我的项目中时,小部件会严重闪烁,这是不可接受的!而且我仍然不得不说我的小部件的 UI 一点也不复杂。
    • 这是另一个问题。您可以接受此答案并发布新答案。延迟是可能的,因为您使用了太重的小部件
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多