Qt Writing Custom Control 64-Vertical Time Axis

I. Preface

Vertical timeline control is mainly used to describe the development process of enterprises, or the iteration history of software versions, etc. It can intuitively display the development process by describing time nodes and events. Generally, such control is often seen in web pages or app s, especially in the company's official gateway, focusing on some Unicorn companies or companies in the booming stage. Used to show how powerful they are, how fast they are developing, etc. Vertical timeline control mainly stores two data, one is time node, the other is event description. In order to expand later period, structure is used to store this data. For example, whether the event belongs to big event marker or not may be added in later period. If yes, it will be highlighted when drawing, such as enlarging the font size. The main difficulty of this control lies in automatic calculation and enlarging the font size. Arrangement to draw time and event description, default to use the mechanism of equivalence to deal with drawing, and some time axis control is left time and right event description, which can be changed or added on the basis of source code. In order to show all events, the main body of the control is inherited from the scrollbar area control, which automatically generates scrollbars beyond the height.

II. Functions of Realization

  • 1: Node margin can be set
  • 2: Settable node height
  • 3: Information border margin can be set
  • 4: The height of information can be set
  • 5: Baseline color/line color can be set
  • 6: Headings/information sets can be set
  • 7: Automatically generate scrollbars
  • 8: Support string format setting data

III. EFFECT CHARACTERISTICS

Header file code

#ifndef TIMEAXIS_H
#define TIMEAXIS_H

/**
 * Author of Vertical Time Axis Control: Yutian Ge (QQ:3246214072) finishing: feiyangqingyun(QQ:517216493) 2019-10-07
 * 1:Settable node margin
 * 2:Settable node height
 * 3:Information border margin can be set
 * 4:Settable height of information
 * 5:Baseline color/line color can be set
 * 6:Settable title/information set
 * 7:Automatic generation of scrollbars
 * 8:Support string format setting data
 */

#include <QScrollArea>
class TimeAxisWidget;

#ifdef quc
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
#include <QtDesigner/QDesignerExportWidget>
#else
#include <QtUiPlugin/QDesignerExportWidget>
#endif

class QDESIGNER_WIDGET_EXPORT TimeAxis : public QScrollArea
#else
class TimeAxis : public QScrollArea
#endif

{
    Q_OBJECT
    Q_PROPERTY(int itemMargin READ getItemMargin WRITE setItemMargin)
    Q_PROPERTY(int itemHeight READ getItemHeight WRITE setItemHeight)
    Q_PROPERTY(int infoPadding READ getInfoPadding WRITE setInfoPadding)
    Q_PROPERTY(int infoHeight READ getInfoHeight WRITE setInfoHeight)

    Q_PROPERTY(QColor baseColor READ getBaseColor WRITE setBaseColor)
    Q_PROPERTY(QColor lineColor READ getLineColor WRITE setLineColor)

    Q_PROPERTY(QString title READ getTitle WRITE setTitle)
    Q_PROPERTY(QString infos READ getInfos WRITE setInfos)

public:
    explicit TimeAxis(QWidget *parent = 0);

private:
    int itemMargin;         //Node margin
    int itemHeight;         //Node Height
    int infoPadding;        //Information margin
    int infoHeight;         //Information Height

    QColor baseColor;       //Benchmark color
    QColor lineColor;       //line color

    QString title;          //Title
    QString infos;          //Information Set

    //Time axis master control
    TimeAxisWidget *timeAxisWidget;

public:
    int getItemMargin()     const;
    int getItemHeight()     const;
    int getInfoPadding()    const;
    int getInfoHeight()     const;

    QColor getBaseColor()   const;
    QColor getLineColor()   const;

    QString getTitle()      const;
    QString getInfos()      const;

    QSize sizeHint()        const;
    QSize minimumSizeHint() const;

    TimeAxisWidget *getWidget();

public Q_SLOTS:
    //Setting node margin + node height
    void setItemMargin(int itemMargin);
    void setItemHeight(int itemHeight);

    //Setting Information Margin + Information Height
    void setInfoPadding(int infoPadding);
    void setInfoHeight(int infoHeight);

    //Set base color + line color
    void setBaseColor(const QColor &baseColor);
    void setLineColor(const QColor &lineColor);

    //Setting Title + Information Set
    void setTitle(const QString &title);
    void setInfos(const QString &infos);
};

class TimeAxisWidget : public QWidget
{
    Q_OBJECT

public:
    //You can expand other information on your own.
    struct TimeAxisInfo {
        QString time;   //time
        QString info;   //information
    };

    explicit TimeAxisWidget(QWidget *parent = 0);

protected:
    void paintEvent(QPaintEvent *);
    void drawTitle(QPainter *painter);
    void drawLine(QPainter *painter);
    void drawInfo(QPainter *painter);
    void drawInfoRight(QPainter *painter, const QRectF &infoRect, int infoHeight);
    void drawInfoLeft(QPainter *painter, const QRectF &infoRect, int infoHeight);

private:
    int itemMargin;         //Node margin
    int itemHeight;         //Node Height
    int infoPadding;        //Information margin
    int infoHeight;         //Information Height

    QColor baseColor;       //Benchmark color
    QColor lineColor;       //line color

    QString title;          //Title
    QString infos;          //Information Set

    //Information aggregate structure
    QList<TimeAxisInfo> itemInfos;

public:
    int getItemMargin()     const;
    int getItemHeight()     const;
    int getInfoPadding()    const;
    int getInfoHeight()     const;

    QColor getBaseColor()   const;
    QColor getLineColor()   const;

    QString getTitle()      const;
    QString getInfos()      const;

    QSize sizeHint()        const;
    QSize minimumSizeHint() const;

public Q_SLOTS:
    //Setting node margin + node height
    void setItemMargin(int itemMargin);
    void setItemHeight(int itemHeight);

    //Setting Information Margin + Information Height
    void setInfoPadding(int infoPadding);
    void setInfoHeight(int infoHeight);

    //Set base color + line color
    void setBaseColor(const QColor &baseColor);
    void setLineColor(const QColor &lineColor);

    //Setting Title + Information Set
    void setTitle(const QString &title);
    void setInfos(const QString &infos);

    //Setting up information set, structure mode
    void setItemInfos(const QList<TimeAxisInfo> &itemInfos);
};

#endif // TIMEAXIS_H


V. Core Code

void TimeAxisWidget::drawTitle(QPainter *painter)
{
    painter->save();

    QFont font;
    font.setBold(true);
    font.setPointSize(16);
    painter->setFont(font);

    painter->setPen(baseColor);
    painter->drawText(itemMargin, itemMargin, width() - 2 * itemMargin, 40, Qt::AlignCenter, title);

    painter->restore();
}

void TimeAxisWidget::drawLine(QPainter *painter)
{
    painter->save();
    painter->setPen(QPen(lineColor, 6));
    int startY = itemMargin + 50;
    int endY = startY + itemInfos.size() * itemHeight;
    painter->drawLine(width() / 2.0, startY, width() / 2.0, endY);
    painter->restore();

    //Set down the fixed height
    this->setFixedHeight(endY + itemMargin);
}

void TimeAxisWidget::drawInfo(QPainter *painter)
{
    painter->save();
    painter->setPen(Qt::NoPen);

    QFont font;
    font.setPointSize(12);
    painter->setFont(font);

    int startY = itemMargin + 50;
    int centerX = this->width() / 2.0;
    int spacer = itemMargin + 10;

    //Trace a set of drawing time axis information, even lines on the left side of drawing time on the right side of drawing information
    for (int i = 0; i < itemInfos.size(); i++) {
        painter->setBrush(Qt::white);
        painter->setPen(QPen(baseColor, 2));

        if (i % 2 == 0) {
            //Drawing time
            QRectF textRect(0, startY, centerX - spacer, itemHeight);
            painter->drawText(textRect, Qt::AlignRight | Qt::AlignVCenter, itemInfos.at(i).time);
            //Drawing Information Border
            QRectF infoRect(centerX + spacer, textRect.center().y() - infoHeight / 2.0, centerX - spacer - itemMargin - infoHeight / 2.0, infoHeight);
            drawInfoRight(painter, infoRect, infoHeight);
            //Drawing Information Background
            painter->setBrush(baseColor);
            drawInfoRight(painter, infoRect.adjusted(infoPadding, infoPadding, 0, -infoPadding), infoHeight - infoPadding * 2);
            //Drawing Information Text
            painter->setPen(Qt::white);
            painter->drawText(infoRect.adjusted(infoPadding, infoPadding, 0, -infoPadding), Qt::AlignCenter, itemInfos.at(i).info);
        } else {
            //Drawing time
            QRectF textRect(centerX + spacer, startY, centerX - spacer, itemHeight);
            painter->drawText(centerX + spacer, startY, centerX - spacer, itemHeight, Qt::AlignLeft | Qt::AlignVCenter, itemInfos.at(i).time);
            //Drawing Information Border
            QRectF infoRect(itemMargin + infoHeight / 2.0, textRect.center().y() - infoHeight / 2.0, centerX - spacer - itemMargin - infoHeight / 2.0, infoHeight);
            drawInfoLeft(painter, infoRect, infoHeight);
            //Drawing Information Background
            painter->setBrush(baseColor);
            drawInfoLeft(painter, infoRect.adjusted(0, infoPadding, -infoPadding, -infoPadding), infoHeight - infoPadding * 2);
            //Drawing Information Text
            painter->setPen(Qt::white);
            painter->drawText(infoRect.adjusted(0, infoPadding, -infoPadding, -infoPadding), Qt::AlignCenter, itemInfos.at(i).info);
        }

        //Draw the circle corresponding to the vertical line
        painter->setPen(Qt::NoPen);
        painter->setBrush(baseColor);
        painter->drawEllipse(centerX - 8, startY + itemHeight / 2.0 - 8, 16, 16);
        painter->setBrush(Qt::white);
        painter->drawEllipse(centerX - 4, startY + itemHeight / 2.0 - 4, 8, 8);

        //Y-axis moves down a height
        startY += itemHeight;
    }

    painter->restore();
}

Introduction of Control

  1. More than 160 exquisite controls, covering a variety of dashboards, progress bars, progress balls, compasses, curves, rulers, thermometers, navigation bars, navigation bars, flatui, highlighted buttons, sliding selectors, the lunar calendar and so on. 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.13, 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 can be set as few attributes, 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, 32 versions of dll have been provided, of which qt_5_7_0_mingw530_32 will always guarantee the latest integrity.
  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 address: https://gitee.com/feiyangqingyun/QUCSDK https://github.com/feiyangqingyun/qucsdk

Tags: Mobile Qt Qt5 Linux SDK

Posted on Wed, 09 Oct 2019 16:31:21 -0400 by rami103