user2777073
user2777073

Reputation: 13

How to resize a frameless widget in Qt

I am researching on how to resize the frameless widget in Qt 5.1. Due to cross-platform consideration, Windows-related codes will not be appropriate.

Now my method is: when a user hovers mouse at the edge of the window(widget),cursor shape changes to hint the window can be resized at that time. After clicking and then drag, a rubberband is being shown to demonstrate the rectangle area that the window would resize to. Once the user releases the mouse, rubberband disappears, and the window then resize to the desired size. Have I made it clear?

Since Qt can't make drawing directly on the screen, as a makeshift, a full screenshot(put in a QLabel) is utilized to simulate the actual screen, and a rubberband can then be constructed in the full-screen QLabel. It seems to the users that they are dragging the window in the real window screen.

My problem is: after the user clicked the main widget,though a full-screen QLabel is shown, the rubberband refuses to appear. Instead, only after you release mouse first and then click-drag again can the rubberband appear.

Although I have sent one "MouseButtonRelease" event to the main widget and a "MouseMove" event to the label, it doesn't seem to work. Any hint or suggestion will be highly appreciated, thanks a lot!

(To simplify the code, any other extra codes have been removed)

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);
    }

Upvotes: 1

Views: 3590

Answers (1)

Dmitry Sazonov
Dmitry Sazonov

Reputation: 8994

You may research how it's done in Qt - QSizeGrip. There are same question

Upvotes: 1

Related Questions