Difference between revisions of "Widget-moveable-and-resizeable"

From Qt Wiki
Jump to: navigation, search
(Add "cleanup" tag)
(Decode HTML entity names)
Line 100: Line 100:
 
     QPoint position;
 
     QPoint position;
 
     QVBoxLayout''' vLayout;
 
     QVBoxLayout''' vLayout;
     void setCursorShape(const QPoint &e_pos);
+
     void setCursorShape(const QPoint &e_pos);
 
     bool eventFilter( QObject *obj, QEvent '''evt );
 
     bool eventFilter( QObject *obj, QEvent '''evt );
 
     void keyPressEvent(QKeyEvent''');
 
     void keyPressEvent(QKeyEvent''');
Line 111: Line 111:
 
     bool m_showMenu;
 
     bool m_showMenu;
 
     bool m_isEditing;
 
     bool m_isEditing;
     void popupShow(const QPoint &pt);
+
     void popupShow(const QPoint &pt);
 
     QWidget '''clone();
 
     QWidget '''clone();
  
Line 182: Line 182:
 
}
 
}
  
void TContainer::popupShow(const QPoint &pt) {
+
void TContainer::popupShow(const QPoint &pt) {
 
     if (menu->isEmpty()) return;
 
     if (menu->isEmpty()) return;
 
     QPoint global = this->mapToGlobal(pt);
 
     QPoint global = this->mapToGlobal(pt);
Line 209: Line 209:
 
     if (m_infocus) {
 
     if (m_infocus) {
 
         QWidget *w = this->parentWidget();
 
         QWidget *w = this->parentWidget();
         if (w  obj && evt->type()QEvent::Paint) {
+
         if (w  obj && evt->type()QEvent::Paint) {
 
             //Рисуем выделение контейнара
 
             //Рисуем выделение контейнара
 
             QPainter painter(w);
 
             QPainter painter(w);
Line 232: Line 232:
 
     if (!m_infocus) return;
 
     if (!m_infocus) return;
 
     //QWidget::mouseMoveEvent(e);
 
     //QWidget::mouseMoveEvent(e);
     if (!e->buttons() & Qt::LeftButton) {
+
     if (!e->buttons() & Qt::LeftButton) {
 
         setCursorShape(e->pos());
 
         setCursorShape(e->pos());
 
         return;
 
         return;
Line 265: Line 265:
 
}
 
}
  
void TContainer::setCursorShape(const QPoint &e_pos) {
+
void TContainer::setCursorShape(const QPoint &e_pos) {
 
     const int diff = 3;
 
     const int diff = 3;
 
     if (
 
     if (
 
             //Left-Bottom
 
             //Left-Bottom
             ((e_pos.y() > y()'' height() - diff) &&          //Bottom
+
             ((e_pos.y() > y()'' height() - diff) &&          //Bottom
 
              (e_pos.x() < x()''diff)) ||                      //Left
 
              (e_pos.x() < x()''diff)) ||                      //Left
 
             //Right-Bottom
 
             //Right-Bottom
             ((e_pos.y() > y()'' height() - diff) &amp;&amp;          //Bottom
+
             ((e_pos.y() > y()'' height() - diff) &&          //Bottom
 
              (e_pos.x() > x() + width() - diff)) ||          //Right
 
              (e_pos.x() > x() + width() - diff)) ||          //Right
 
             //Left-Top
 
             //Left-Top
             ((e_pos.y() < y() + diff) &amp;&amp;                     //Top
+
             ((e_pos.y() < y() + diff) &&                     //Top
 
              (e_pos.x() < x() + diff)) ||                    //Left
 
              (e_pos.x() < x() + diff)) ||                    //Left
 
             //Right-Top
 
             //Right-Top
             ((e_pos.y() < y() + diff) &amp;&amp;                     //Top
+
             ((e_pos.y() < y() + diff) &&                     //Top
 
              (e_pos.x() > x() + width() - diff))             //Right
 
              (e_pos.x() > x() + width() - diff))             //Right
 
        )
 
        )
 
     {
 
     {
 
         //Left-Bottom
 
         //Left-Bottom
         if ((e_pos.y() > y() + height() - diff) &amp;&amp;           //Bottom
+
         if ((e_pos.y() > y() + height() - diff) &&           //Bottom
 
             (e_pos.x() < x() + diff)) {                      //Left
 
             (e_pos.x() < x() + diff)) {                      //Left
 
             mode = RESIZEBL;
 
             mode = RESIZEBL;
Line 289: Line 289:
 
         }
 
         }
 
         //Right-Bottom
 
         //Right-Bottom
         if ((e_pos.y() > y() + height() - diff) &amp;&amp;           //Bottom
+
         if ((e_pos.y() > y() + height() - diff) &&           //Bottom
 
             (e_pos.x() > x() + width() - diff)) {            //Right
 
             (e_pos.x() > x() + width() - diff)) {            //Right
 
             mode = RESIZEBR;
 
             mode = RESIZEBR;
Line 295: Line 295:
 
         }
 
         }
 
         //Left-Top
 
         //Left-Top
         if ((e_pos.y() < y() + diff) &amp;&amp;                      //Top
+
         if ((e_pos.y() < y() + diff) &&                      //Top
 
             (e_pos.x() < x() + diff)) {                      //Left
 
             (e_pos.x() < x() + diff)) {                      //Left
 
             mode = RESIZETL;
 
             mode = RESIZETL;
Line 301: Line 301:
 
         }
 
         }
 
         //Right-Top
 
         //Right-Top
         if ((e_pos.y() < y() + diff) &amp;&amp;                      //Top
+
         if ((e_pos.y() < y() + diff) &&                      //Top
 
             (e_pos.x() > x() + width() - diff)) {            //Right
 
             (e_pos.x() > x() + width() - diff)) {            //Right
 
             mode = RESIZETR;
 
             mode = RESIZETR;
Line 342: Line 342:
 
     if (!m_isEditing) return;
 
     if (!m_isEditing) return;
 
     if (!m_infocus) return;
 
     if (!m_infocus) return;
     if (!e->buttons() &amp; Qt::LeftButton) {
+
     if (!e->buttons() & Qt::LeftButton) {
 
         QPoint p = QPoint(e->x()+geometry().x(), e->y()+geometry().y());
 
         QPoint p = QPoint(e->x()+geometry().x(), e->y()+geometry().y());
 
         setCursorShape(p);
 
         setCursorShape(p);
Line 348: Line 348:
 
     }
 
     }
  
   if ((mode  MOVE || mode  NONE) &amp;&amp; e->buttons() &amp;&amp; Qt::LeftButton) {
+
   if ((mode  MOVE || mode  NONE) && e->buttons() && Qt::LeftButton) {
 
         QPoint toMove = e->globalPos() - position;
 
         QPoint toMove = e->globalPos() - position;
 
         if (toMove.x() < 0) return;
 
         if (toMove.x() < 0) return;
Line 358: Line 358:
 
         return;
 
         return;
 
     }
 
     }
     if ((mode != MOVE) &amp;&amp; e->buttons() &amp;&amp; Qt::LeftButton) {
+
     if ((mode != MOVE) && e->buttons() && Qt::LeftButton) {
 
         switch (mode){
 
         switch (mode){
 
             case RESIZETL: {  //Left-Top
 
             case RESIZETL: {  //Left-Top

Revision as of 17:54, 12 March 2015

I want to present a widget which can be moved and at which it is possible to change the sizes. This widget can serve as the container for other widgets, such as to QLabel, QTableWidget and so on. This widget is used by me already in several projects. I hope it we will to you it is useful mainwindow.h /* Programmer Aleksey Osipov email: aliks-os@yandex.ru
  • /
  1. ifndef MAINWINDOW_H
  2. define MAINWINDOW_H
  1. include <QMainWindow>
  2. include "tcontainer.h"
namespace Ui { class MainWindow; } class MainWindow : public QMainWindow {    Q_OBJECT     public:    explicit MainWindow(QWidget *parent = 0);    ~MainWindow();     private:    Ui::MainWindow ui; };
  1. endif // MAINWINDOW_H
mainwindow.cpp / Programmer Aleksey Osipov email: aliks-os@yandex.ru
  • /
  1. include "mainwindow.h"
  2. include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :  QMainWindow(parent),  ui(new Ui::MainWindow) {    ui->setupUi(this);    this->showMaximized();    QLabel *lab1 = new QLabel("Label1");    QLabel *lab2 = new QLabel("Label2");    TContainer *con1 = new TContainer(this,QPoint(10,10),lab1);    TContainer con2 = new TContainer(this,QPoint(20,50),lab2); } MainWindow::~MainWindow() {    delete ui; }
tcontainer.h / Programmer Aleksey Osipov email: aliks-os@yandex.ru
  • /
  1. ifndef TCONTAINER_H
  2. define TCONTAINER_H
  1. include <QWidget>
  2. include <QMouseEvent>
  3. include <QtGui>
enum modes{    NONE = 0,    MOVE = 1,    RESIZETL = 2,    RESIZET = 3,    RESIZETR = 4,    RESIZER = 5,    RESIZEBR = 6,    RESIZEB = 7,    RESIZEBL = 8,    RESIZEL = 9 }; class TContainer : public QWidget {    Q_OBJECT public:    TContainer(QWidget *parent, QPoint p, QWidget *cWidget = 0);    ~TContainer();    QWidget *childWidget;    QMenu *menu;    void setChildWidget(QWidget cWidget); protected:    int mode;    QPoint position;    QVBoxLayout vLayout;    void setCursorShape(const QPoint &e_pos);    bool eventFilter( QObject *obj, QEvent evt );    void keyPressEvent(QKeyEvent);    void focusInEvent(QFocusEvent );    void focusOutEvent(QFocusEvent);    void mousePressEvent(QMouseEvent );    void mouseReleaseEvent(QMouseEvent);    void mouseMoveEvent(QMouseEvent *);    bool m_infocus;    bool m_showMenu;    bool m_isEditing;    void popupShow(const QPoint &pt);    QWidget clone(); private: signals:    void inFocus(bool mode);    void outFocus(bool mode);    void newGeometry(QRect rect); public slots: };
  1. endif // TCONTAINER_H
tcontainer.cpp / Programmer Aleksey Osipov email: aliks-os@yandex.ru
  • /
  1. include "tcontainer.h"
TContainer::TContainer(QWidget *parent, QPoint p, QWidget *cWidget) : QWidget(parent) {    mode = NONE;    childWidget = cWidget;    setAttribute(Qt::WA_DeleteOnClose);    this->setVisible(true);    this->setAutoFillBackground(false);    this->setMouseTracking(true);    this->setFocusPolicy(Qt::ClickFocus);    this->setFocus();    this->move(p);    vLayout = new QVBoxLayout(this);    if (cWidget != 0) {        cWidget->setParent(this);        cWidget->releaseMouse();        cWidget->setAttribute(Qt::WA_TransparentForMouseEvents, true);        vLayout->addWidget(cWidget);        vLayout->setContentsMargins(0,0,0,0);    }    this->setLayout(vLayout);    m_infocus = true;    m_showMenu = false;    m_isEditing = true;    this->installEventFilter(parent); } TContainer::~TContainer() {    delete vLayout; } void TContainer::setChildWidget(QWidget *cWidget) {    if (cWidget != 0) {        childWidget = cWidget;        childWidget->setAttribute(Qt::WA_TransparentForMouseEvents, true);        childWidget->setParent(this);        vLayout->addWidget(cWidget);        vLayout->setContentsMargins(0,0,0,0);    } } void TContainer::popupShow(const QPoint &pt) {    if (menu->isEmpty()) return;    QPoint global = this->mapToGlobal(pt);    m_showMenu = true;    menu->exec(global);    m_showMenu = false; } void TContainer::focusInEvent(QFocusEvent *e) {    m_infocus = true;    this->parentWidget()->installEventFilter(this);    this->parentWidget()->repaint();    emit inFocus(true); } void TContainer::focusOutEvent(QFocusEvent *e) {    if (!m_isEditing) return;    if (m_showMenu) return;    mode = NONE;    emit outFocus(false);    m_infocus = false; } bool TContainer::eventFilter( QObject *obj, QEvent *evt ) {    //return QWidget::eventFilter(obj, evt);    if (m_infocus) {        QWidget *w = this->parentWidget();        if (w obj && evt->type()QEvent::Paint) {            //Рисуем выделение контейнара            QPainter painter(w);            QPoint p = this->mapTo(w,QPoint(–3,-3));            QPoint LT = w->mapFrom(w,p);            QPoint LB = w->mapFrom(w,QPoint(p.x(),p.y()+this->height()));            QPoint RB = w->mapFrom(w,QPoint(p.x()+this->width(),p.y()+this->height()));            QPoint RT = w->mapFrom(w,QPoint(p.x()+this->width(),p.y()));            painter.fillRect(LT.x(),LT.y(),6,6,QColor("black"));            painter.fillRect(LB.x(),LB.y(),6,6,QColor("black"));            painter.fillRect(RB.x(),RB.y(),6,6,QColor("black"));            painter.fillRect(RT.x(),RT.y(),6,6,QColor("black"));            return QWidget::eventFilter(obj,evt);        }    }    return QWidget::eventFilter(obj, evt);} void TContainer::mousePressEvent(QMouseEvent *e) {    position = QPoint(e->globalX()-geometry().x(), e->globalY()-geometry().y());    if (!m_isEditing) return;    if (!m_infocus) return;    //QWidget::mouseMoveEvent(e);    if (!e->buttons() & Qt::LeftButton) {        setCursorShape(e->pos());        return;    }    if(e->button()==Qt::RightButton) {        popupShow(e->pos());        e->accept();    } } void TContainer::keyPressEvent(QKeyEvent *e) {    if (!m_isEditing) return;    if (e->key() Qt::Key_Delete) {        this->deleteLater();    }    //Двигаем контайнер при помощи клавиш    if (QApplication::keyboardModifiers() Qt::ControlModifier) {        QPoint newPos(this->x(),this->y());        if (e->key() Qt::Key_Up) newPos.setY(newPos.y()-1);        if (e->key() Qt::Key_Down) newPos.setY(newPos.y()+1);        if (e->key() Qt::Key_Left) newPos.setX(newPos.x()-1);        if (e->key() Qt::Key_Right) newPos.setX(newPos.x()+1);        move(newPos);    }    if (QApplication::keyboardModifiers() Qt::ShiftModifier) {        if (e->key() Qt::Key_Up) resize(width(),height()-1);        if (e->key() Qt::Key_Down) resize(width(),height()+1);        if (e->key() Qt::Key_Left) resize(width()-1,height());        if (e->key() == Qt::Key_Right) resize(width()1,height());    }    emit newGeometry(this->geometry()); } void TContainer::setCursorShape(const QPoint &e_pos) {    const int diff = 3;    if (            //Left-Bottom            ((e_pos.y() > y() height() - diff) &&          //Bottom             (e_pos.x() < x()diff)) ||                      //Left            //Right-Bottom            ((e_pos.y() > y() height() - diff) &&          //Bottom             (e_pos.x() > x() + width() - diff)) ||          //Right            //Left-Top            ((e_pos.y() < y() + diff) &&                     //Top             (e_pos.x() < x() + diff)) ||                    //Left            //Right-Top            ((e_pos.y() < y() + diff) &&                     //Top             (e_pos.x() > x() + width() - diff))             //Right       )    {        //Left-Bottom        if ((e_pos.y() > y() + height() - diff) &&           //Bottom            (e_pos.x() < x() + diff)) {                      //Left            mode = RESIZEBL;            setCursor(QCursor(Qt::SizeBDiagCursor));        }        //Right-Bottom        if ((e_pos.y() > y() + height() - diff) &&           //Bottom            (e_pos.x() > x() + width() - diff)) {            //Right            mode = RESIZEBR;            setCursor(QCursor(Qt::SizeFDiagCursor));        }        //Left-Top        if ((e_pos.y() < y() + diff) &&                      //Top            (e_pos.x() < x() + diff)) {                      //Left            mode = RESIZETL;            setCursor(QCursor(Qt::SizeFDiagCursor));        }        //Right-Top        if ((e_pos.y() < y() + diff) &&                      //Top            (e_pos.x() > x() + width() - diff)) {            //Right            mode = RESIZETR;            setCursor(QCursor(Qt::SizeBDiagCursor));        }    }    // проверка положения курсора по горизонтали    else if ((e_pos.x() < x() + diff) ||             //Left            ((e_pos.x() > x() + width() - diff))) {  //Right        if (e_pos.x() < x() + diff) {                //Left            setCursor(QCursor(Qt::SizeHorCursor));            mode = RESIZEL;        } else {                                     //Right            setCursor(QCursor(Qt::SizeHorCursor));            mode = RESIZER;        }    }    // проверка положения курсора по вертикали    else if (((e_pos.y() > y() + height() - diff)) || //Bottom              (e_pos.y() < y() + diff)) {             //Top        if (e_pos.y() < y() + diff) {                 //Top            setCursor(QCursor(Qt::SizeVerCursor));            mode = RESIZET;        } else {                                      //Bottom            setCursor(QCursor(Qt::SizeVerCursor));            mode = RESIZEB;        }    } else {        setCursor(QCursor(Qt::ArrowCursor));        mode = MOVE;    } } void TContainer::mouseReleaseEvent(QMouseEvent *e) {    QWidget::mouseReleaseEvent(e); } void TContainer::mouseMoveEvent(QMouseEvent *e) {    QWidget::mouseMoveEvent(e);    if (!m_isEditing) return;    if (!m_infocus) return;    if (!e->buttons() & Qt::LeftButton) {        QPoint p = QPoint(e->x()+geometry().x(), e->y()+geometry().y());        setCursorShape(p);        return;    }    if ((mode MOVE || mode NONE) && e->buttons() && Qt::LeftButton) {        QPoint toMove = e->globalPos() - position;        if (toMove.x() < 0) return;        if (toMove.y() < 0) return;        if (toMove.x() > this->parentWidget()->width()-this->width()) return;        move(toMove);        emit newGeometry(this->geometry());        this->parentWidget()->repaint();        return;    }    if ((mode != MOVE) && e->buttons() && Qt::LeftButton) {        switch (mode){            case RESIZETL: {  //Left-Top                int newwidth = e->globalX() - position.x() - geometry().x();                int newheight = e->globalY() - position.y() - geometry().y();                QPoint toMove = e->globalPos() - position;                resize(this->geometry().width()-newwidth,this->geometry().height()-newheight);                move(toMove.x(),toMove.y());                break;            }            case RESIZETR: {  //Right-Top                int newheight = e->globalY() - position.y() - geometry().y();                QPoint toMove = e->globalPos() - position;                resize(e->x(),this->geometry().height()-newheight);                move(this->x(),toMove.y());                break;            }            case RESIZEBL: {  //Left-Bottom                int newwidth = e->globalX() - position.x() - geometry().x();                QPoint toMove = e->globalPos() - position;                resize(this->geometry().width()-newwidth,e->y());                move(toMove.x(),this->y());                break;            }            case RESIZEB: {   //Bottom                resize(width(),e->y()); break;}            case RESIZEL:  {  //Left                int newwidth = e->globalX() - position.x() - geometry().x();                QPoint toMove = e->globalPos() - position;                resize(this->geometry().width()-newwidth,height());                move(toMove.x(),this->y());                break;            }            case RESIZET:  {  //Top                int newheight = e->globalY() - position.y() - geometry().y();                QPoint toMove = e->globalPos() - position;                resize(width(),this->geometry().height()-newheight);                move(this->x(),toMove.y());                break;            }            case RESIZER:  {  //Right                resize(e->x(),height()); break;}            case RESIZEBR: {  //Right-Bottom                resize(e->x(),e->y()); break;}        }        this->parentWidget()->repaint();    }    emit newGeometry(this->geometry());    //QWidget::mouseMoveEvent(e); }