Qt Writing Control Property Designer 3 - Stretch Control

I. Preface

Plug-in controls are loaded and drag controls are implemented. Next is the most difficult point. Like QtDesigner or other development environments, it can stretch control size and move position freely. In order to achieve this function, a control named SelectWidget Trace Following is specially designed. Form control, the general principle is to install event filters, when the control is generated, the control is passed into the tracing point following control, automatically identify the mouse position, press the pull distance to change the size of the control, draw the tracing point indicator for users to stretch. The tracing point follow control can set whether to draw the tracing point, the margin, the color of the tracing point, the size of the tracing point, the square + circle of the tracing point style, and the width of the selected border. It can support the upper and lower buttons to move the form, the delete key to delete the form, and eight tracing points to change the size and size of the form. Experience address: https://pan.baidu.com/s/1A5Gd77kExm8Co5ckT51vvQ Extraction code: 877p file: executable file. zip

II. Functions of Realization

  1. All controls in the plug-in file are automatically loaded to generate lists. By default, there are more than 120 controls in the plug-in file.
  2. Drag onto the canvas to automatically generate the corresponding control, WYSIWYG.
  3. On the right side of the Chinese property bar, changing the corresponding properties is immediately applied to the selected control, intuitive and concise, very suitable for the use of Xiaobai.
  4. The original attribute bar text translation mapping mechanism is very efficient and can be very convenient to expand the attribute bar of other languages.
  5. The properties of all controls are automatically extracted and displayed in the right property bar, including the enumeration value drop-down box, etc.
  6. Support manual selection of plug-in files and external import of plug-in files.
  7. All control configuration information for the current canvas can be exported to an xml file.
  8. You can manually select the xml file to open the control layout and automatically load the control according to the xml file.
  9. Pull slider, check analog data check box, text box input, three ways to generate data and apply all controls.
  10. Control supports eight azimuth pull to adjust size, adaptive arbitrary resolution, and keyboard position can be fine-tuned from top to bottom.
  11. Through the serial port acquisition, network acquisition, database acquisition three ways to set up data.
  12. The code is extremely concise, the comments are very detailed, can be used as the embryonic configuration, expand more functions.
  13. Pure Qt programming, support any Qt version + any compiler + any system.

III. EFFECT CHARACTERISTICS

Core Code

bool SelectWidget::eventFilter(QObject *watched, QEvent *event)
{
    if (watched == widget) {
        if (event->type() == QEvent::Resize) {
            //Set the current form size to follow the increase in form size
            this->resize(this->widget->size() + QSize(padding * 2, padding * 2));
        } else if (event->type() == QEvent::Move) {
            //Move the current form to offset
            this->move(this->widget->pos() - QPoint(padding, padding));
        }
    } else {
        if (event->type() == QEvent::KeyPress) {
            QKeyEvent *keyEvent = dynamic_cast<QKeyEvent *>(event);
            if (keyEvent->key() == Qt::Key_Left) {
                this->move(this->pos() - QPoint(1, 0));
            } else if (keyEvent->key() == Qt::Key_Right) {
                this->move(this->pos() + QPoint(1, 0));
            } else if (keyEvent->key() == Qt::Key_Up) {
                this->move(this->pos() - QPoint(0, 1));
            } else if (keyEvent->key() == Qt::Key_Down) {
                this->move(this->pos() + QPoint(0, 1));
            } else if (keyEvent->key() == Qt::Key_Delete) {
                emit widgetDelete(widget);
                widget->deleteLater();
                this->deleteLater();
                widget = 0;
            }

            //Reset the location and size of the attached form
            if (widget != 0) {
                widget->setGeometry(this->x() + padding, this->y() + padding, this->width() - padding * 2, this->height() - padding * 2);
            }

            return QWidget::eventFilter(watched, event);
        }

        QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
        if (mouseEvent->type() == QEvent::MouseButtonPress) {
            //Keep in mind the coordinates and width of the current control and the coordinates pressed by the mouse
            rectX = this->x();
            rectY = this->y();
            rectW = this->width();
            rectH = this->height();
            lastPos = mouseEvent->pos();

            //Judge the area position of the pressed handle
            if (rectLeft.contains(lastPos)) {
                pressedLeft = true;
            } else if (rectRight.contains(lastPos)) {
                pressedRight = true;
            } else if (rectTop.contains(lastPos)) {
                pressedTop = true;
            } else if (rectBottom.contains(lastPos)) {
                pressedBottom = true;
            } else if (rectLeftTop.contains(lastPos)) {
                pressedLeftTop = true;
            } else if (rectRightTop.contains(lastPos)) {
                pressedRightTop = true;
            } else if (rectLeftBottom.contains(lastPos)) {
                pressedLeftBottom = true;
            } else if (rectRightBottom.contains(lastPos)) {
                pressedRightBottom = true;
            } else {
                pressed = true;
            }

            if (widget != 0) {
                emit widgetPressed(widget);
            }
        } else if (mouseEvent->type() == QEvent::MouseMove) {
            //Calculate how much the XY axis has moved based on the current mouse position
            QPoint pos = mouseEvent->pos();
            int dx = pos.x() - lastPos.x();
            int dy = pos.y() - lastPos.y();

            //Determine whether a mobile control or a stretch control is based on the position at which it is pressed
            if (pressed) {
                this->move(this->x() + dx, this->y() + dy);
            } else if (pressedLeft) {
                int resizeW = this->width() - dx;
                if (this->minimumWidth() <= resizeW) {
                    this->setGeometry(this->x() + dx, rectY, resizeW, rectH);
                }
            } else if (pressedRight) {
                this->setGeometry(rectX, rectY, rectW + dx, rectH);
            } else if (pressedTop) {
                int resizeH = this->height() - dy;
                if (this->minimumHeight() <= resizeH) {
                    this->setGeometry(rectX, this->y() + dy, rectW, resizeH);
                }
            } else if (pressedBottom) {
                this->setGeometry(rectX, rectY, rectW, rectH + dy);
            } else if (pressedLeftTop) {
                int resizeW = this->width() - dx;
                int resizeH = this->height() - dy;
                if (this->minimumWidth() <= resizeW) {
                    this->setGeometry(this->x() + dx, this->y(), resizeW, resizeH);
                }
                if (this->minimumHeight() <= resizeH) {
                    this->setGeometry(this->x(), this->y() + dy, resizeW, resizeH);
                }
            } else if (pressedRightTop) {
                int resizeW = rectW + dx;
                int resizeH = this->height() - dy;
                if (this->minimumHeight() <= resizeH) {
                    this->setGeometry(this->x(), this->y() + dy, resizeW, resizeH);
                }
            } else if (pressedLeftBottom) {
                int resizeW = this->width() - dx;
                int resizeH = rectH + dy;
                if (this->minimumWidth() <= resizeW) {
                    this->setGeometry(this->x() + dx, this->y(), resizeW, resizeH);
                }
                if (this->minimumHeight() <= resizeH) {
                    this->setGeometry(this->x(), this->y(), resizeW, resizeH);
                }
            } else if (pressedRightBottom) {
                int resizeW = rectW + dx;
                int resizeH = rectH + dy;
                this->setGeometry(this->x(), this->y(), resizeW, resizeH);
            }

            //Reset the location and size of the attached form
            if (widget != 0) {
                widget->setGeometry(this->x() + padding, this->y() + padding, this->width() - padding * 2, this->height() - padding * 2);
            }
        } else if (mouseEvent->type() == QEvent::MouseButtonRelease) {
            pressed = false;
            pressedLeft = false;
            pressedRight = false;
            pressedTop = false;
            pressedBottom = false;
            pressedLeftTop = false;
            pressedRightTop = false;
            pressedLeftBottom = false;
            pressedRightBottom = false;

            if (widget != 0) {
                emit widgetRelease(widget);
            }
        }
    }

    return QWidget::eventFilter(watched, event);
}

void SelectWidget::resizeEvent(QResizeEvent *)
{
    //To recalculate the area of eight tracing points, the function of the tracing point area is to calculate whether the mouse coordinates are in a certain area or not.
    int width = this->width();
    int height = this->height();

    //Left tracing area
    rectLeft = QRectF(0, height / 2 - pointSize / 2, pointSize, pointSize);
    //Topside tracing area
    rectTop = QRectF(width / 2 - pointSize / 2, 0, pointSize, pointSize);
    //Right tracing area
    rectRight = QRectF(width - pointSize, height / 2 - pointSize / 2, pointSize, pointSize);
    //Lower outline area
    rectBottom = QRectF(width / 2 - pointSize / 2, height - pointSize, pointSize, pointSize);

    //Top left corner tracing area
    rectLeftTop = QRectF(0, 0, pointSize, pointSize);
    //Top right corner tracing area
    rectRightTop = QRectF(width - pointSize, 0, pointSize, pointSize);
    //The lower left corner tracing area
    rectLeftBottom = QRectF(0, height - pointSize, pointSize, pointSize);
    //The lower right corner tracing area
    rectRightBottom = QRectF(width - pointSize, height - pointSize, pointSize, pointSize);
}

void SelectWidget::mouseMoveEvent(QMouseEvent *e)
{
    //Calculate whether the current mouse position is in an area, automatically update the mouse shape
    QPoint p = e->pos();
    if (rectLeft.contains(p)) {
        this->setCursor(Qt::SizeHorCursor);
    } else if (rectTop.contains(p)) {
        this->setCursor(Qt::SizeVerCursor);
    } else if (rectRight.contains(p)) {
        this->setCursor(Qt::SizeHorCursor);
    } else if (rectBottom.contains(p)) {
        this->setCursor(Qt::SizeVerCursor);
    } else if (rectLeftTop.contains(p)) {
        this->setCursor(Qt::SizeFDiagCursor);
    } else if (rectRightTop.contains(p)) {
        this->setCursor(Qt::SizeBDiagCursor);
    } else if (rectLeftBottom.contains(p)) {
        this->setCursor(Qt::SizeBDiagCursor);
    } else if (rectRightBottom.contains(p)) {
        this->setCursor(Qt::SizeFDiagCursor);
    } else {
        this->setCursor(Qt::ArrowCursor);
    }
}

Introduction of Control

  1. More than 150 exquisite controls, covering a variety of dashboards, progress bars, progress balls, compasses, curves, rulers, thermometers, navigation bars, navigation bars, flatui, highlighted buttons, sliding selectors, lunar calendar, etc. Far more controls than qwt integrates.
  2. Each class can be separated into a separate control, zero-coupling, each control has a header file and an implementation file, independent of other files, to facilitate the integration of a single control in the form of source code into the project, less code. The control classes of qwt are interlinked and highly coupled. If you want to use one of the controls, you must include all the code.
  3. All pure Qt writing, QWidget+QPainter drawing, support any Qt version from Qt4.6 to Qt5.12, support mingw, msvc, gcc and other compilers, support any operating system such as windows+linux+mac + embedded linux, no scrambling, can be directly integrated into Qt Creator, as with its own controls, most of the effects as long as set up. Several attributes can be used, which is very convenient.
  4. Each control has a corresponding separate DEMO containing the source code of the control, which is convenient for reference. It also provides an integrated DEMO for all controls.
  5. The source code of each control has detailed Chinese annotations, which are compiled in accordance with the unified design specifications. It is convenient to learn how to compile custom controls.
  6. Each control's default color matching and demo's corresponding color matching are very beautiful.
  7. More than 130 visible controls and 6 invisible controls.
  8. Some controls provide a variety of style choices, a variety of indicator style choices.
  9. All controls adapt to form stretching changes.
  10. Integrate custom control property designer, support drag design, WYSIWYG, support import and export xml format.
  11. With activex control demo, all controls can run directly in ie browser.
  12. Integrate fontawesome graphic fonts + hundreds of graphic fonts collected by Alibaba iconfont to enjoy the fun of graphic fonts.
  13. All controls eventually generate a dynamic library file (dll or so, etc.) that can be directly integrated into the qtcreator to drag the design to use.
  14. At present, there is a version of qml, pyqt version will be considered later, if the user demand is large.
  15. Custom Control Plug-in Open Dynamic Library (permanently free), without any backdoor and restrictions, please feel free to use.
  16. At present, 26 versions of dll have been provided, including qt5.12.3 MSVC 2017 32 + 64 MinGW 32 + 64.
  17. Increase control and improve control from time to time, update SDK from time to time. Welcome to make suggestions. Thank you!
  18. Qt introductory books recommend Hoyafei's Quick Start to Qt Creator, Qt5 Programming Introduction, and Qt advanced books recommend the official C++ GUI Qt4 Programming.
  19. I strongly recommend programmers'self-cultivation and planning series "Talking about Programmers", "Programmers' Growth Course" and "Solution Programmers". They benefit a lot and benefit a lifetime!
  20. SDK Download Link: https://pan.baidu.com/s/1A5Gd77kExm8Co5ckT51vvQ Extraction code: 877p

Tags: Mobile Qt xml Programming Qt5

Posted on Tue, 10 Sep 2019 01:54:44 -0700 by Scrumpers