2

I'm beginner in Qt and I want to drag and move Window using my own custom titleBar(QLabel).

The Qt code:

void MainWindow::mousePressEvent(QMouseEvent *event)
{
    mpos = event->pos();
}

void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() & Qt::LeftButton) 
    {
        QPoint diff = event->pos() - mpos;
        QPoint newpos = this->pos() + diff;
        this->move(newpos);
    }
}

This code allow me to move window by mouse pressed on any QWidget but I want to move window by mouse pressed on QLabel.

Farhad
  • 4,119
  • 8
  • 43
  • 66
  • QLable is a driven class from QWidget you can install events or erimplement Qlabel calss fro custom class and code for mouseMoveEvent – saeed Sep 16 '17 at 16:55
  • A working solution, provided by me, is given in https://stackoverflow.com/a/60659234/10060901 – Vinu Raja Kumar C Mar 12 '20 at 17:41

3 Answers3

2

I know that its kinda late, but I solved this issue. The code is very similar to the implementation that Farhad suggested, but to solve the "jumping" window, you need to update the current position of the mouse also in the event filter:

 if (object == ui->frame_title && event->type() == QEvent::MouseButtonPress)
        {
            QMouseEvent* mouseEvent = (QMouseEvent*)event;
            if (pressed == false){
                current = mouseEvent->pos();
            }
            pressed = true;
            return true;
        }

Adding this, you get the current mouse location when the user first press the left-click.

Here is the full implementation:

void MainWindow::mousePressEvent(QMouseEvent *event)
{
    current = event->pos();
}

void MainWindow::mouseMoveEvent(QMouseEvent *event)
{

    if(pressed)
        this->move(mapToParent(event->pos() - current));
}

bool MainWindow::eventFilter(QObject *object, QEvent *event)
{
    if (object == ui->frame_title && event->type() == QEvent::MouseButtonPress)
    {
        QMouseEvent* mouseEvent = (QMouseEvent*)event;
        if (pressed == false){
            current = mouseEvent->pos();
        }
        pressed = true;
        return true;
    }
    if (object == ui->frame_title && event->type() == QEvent::MouseButtonRelease)
    {
        pressed = false;
        return true;
    }
    else
        return false;
}

Then in your constructor, just add (frame_title is my titlebar):

ui->frame_title->installEventFilter(this);
facureyes
  • 41
  • 2
  • 4
  • 1
    Welcome to Stack Overflow. Code-only answers are discouraged on Stack Overflow because they don't explain how it solves the problem. Please edit your answer to explain what this code does and how it fixes the problem, so that it is useful to other users with similar issues. – FluffyKitten Sep 06 '20 at 01:30
  • 1
    @FluffyKitten thanks, you are right! there I put more explanation! – facureyes Sep 06 '20 at 16:59
  • Much better :) That makes it a great answer! – FluffyKitten Sep 06 '20 at 17:02
1

You can re-implement QLabel class and impalement mousePressEvent

Example :

header file

#ifndef MYLABLE_H

#define MYLABLE_H

#include <QEvent>
#include <QObject>
#include <QLabel>

class MyLable : public QLabel
{
    Q_OBJECT
public:
    explicit MyLable(QWidget *parent = 0);

    QPoint mpos;

signals:

public slots:



    // QWidget interface
protected:
    void mousePressEvent(QMouseEvent *);
};

#endif // MYLABLE_H

.cpp

#include "mylable.h"

#include <QMouseEvent>

MyLable::MyLable(QWidget *parent) : QLabel(parent)
{
}

void MyLable::mousePressEvent(QMouseEvent * event)
{
    if (event->buttons() & Qt::LeftButton)
    {
        QPoint diff = event->pos() - mpos;
        QPoint newpos = this->pos() + diff;
        this-> parentWidget()->move(newpos);
    }
}
saeed
  • 2,477
  • 2
  • 23
  • 40
1

I suggest you to use eventFilter to get event MousePress and MouseRelease:

void MainApp::mousePressEvent(QMouseEvent *event)
{
    current = event->pos();
}

void MainApp::mouseMoveEvent(QMouseEvent *event)
{
    if(pressed)
        this->move(mapToParent(event->pos() - current));
}

bool MainApp::eventFilter(QObject *object, QEvent *event)
{
    if (object == ui->label && event->type() == QEvent::MouseButtonPress)
    {
        pressed = true;
        return true;
    }
    if (object == ui->label && event->type() == QEvent::MouseButtonRelease)
    {
        pressed = false;
        return true;
    }
    else
        return false;
}

This is a sample project for your question on github download here.

Farhad
  • 4,119
  • 8
  • 43
  • 66