C++,Qt垂直时间线控件 ,基于QWidget实现,不支持复杂交互事件

按照惯例,先上图,视频演示请移步作者B站链接

完全基于QWidget,根据数据动态计算高度并进行绘图,占用内存较少,数据多的时候渲染较慢

风格定义结构体代码如下

//垂直时间线全局数据结构
  typedef struct QVERTTIMERLINE_DATAS_ {
    int    nItemsMargin = 10;                                  //节点边距
    int    nItemsHeight = 48;                                  //最小节点高度
    int    nInfoPadding = 6;                                   //内容边距
    int    nInfoHeights = 40;                                  //信息最小高度
    uint   uAxislyAlign = 0;                                   //轴向对齐方式,0中间,1左侧,2右侧
    uint   uTimersWidth = 120;                                 //时间区域宽度

    double dAxislyWidth = 4.0;                                 //轴宽度
    double dBorderWidth = 2.0;                                 //内容区域边框宽度
    double dBorderTitle = 1.0;                                 //标题区域边框宽度
    double dBorderTimer = 1.0;                                 //时间区域边框宽度
    double dBorderGroup = 1.0;                                 //分组区域边框宽度

    double dTextsRadius = 0.5;                                 //文本区域圆角比例
    double dTimerRadius = 0.5;                                 //时间区域圆角比例
    double dGroupRadius = 0.5;                                 //分组区域圆角比例
    double dTitleRadius = 0.5;                                 //标题区域圆角比例

    bool   bFixedRadius = false;                               //是否使用固定圆角值
    uint   uFixedRadius = 10;                                  //内容圆角半径绝对值

    //以右侧内容为参考,左侧内容与之相反
    uint   uTxtRadiusId = 0;                                   //内容区域圆角风格,0,左下角锐角,1左上角锐角,2右上角锐角,3右下角锐角,4全部圆角,5左侧两个角圆角,6右侧两个角圆角,7上侧两个角圆角,8下侧两个角圆角,9全部锐角,10左下和右上锐角,11左上和右下锐角
    uint   uTagRadiusId = 4;                                   //时间圆角风格,与内容圆角风格一致
    uint   uGroupRadius = 4;                                   //分组圆角风格,与内容圆角风格一致
    uint   uTitleRadius = 4;                                   //标题圆角风格,与内容圆角风格一致

    uint   uStartRadius = 4;                                   //开始点半径
    uint   uEndlyRadius = 18;                                  //结束点半径

    int    nPointRadius = 6;                                   //中心点半径

    QColor cAxislyColor = QColor(170, 170, 255);               //轴颜色
    QColor cCenterColor = QColor(255, 85, 127);                //中心点颜色
    QColor cCenterFrame = QColor(85, 170, 127);                //中心点边框颜色
    QColor cTitleColors = QColor(255,255,255);                 //标题文字颜色
    QColor cTitleBkgClr = QColor(192,192,192,88);              //标题背景颜色
    QColor cTitleBorder = QColor(192,192,192,127);             //标题边框颜色
    QColor cTimeBorders = QColor(255,170,127,66);              //时间边框颜色
    QColor cTimeBkgClrs = QColor(255, 170, 127,44);            //时间背景颜色
    QColor cBasedColors = QColor(0,170,127);                   //基准颜色
    QColor cBorderColor = QColor(255, 170, 127);               //边框颜色
    QColor cTimerColors = QColor(192,192,192);                 //时间颜色
    QColor cTextsColors = QColor(255,255,255);                 //文本内容颜色

    QColor cGroupsColor = QColor(240,240,240);                 //分组标题颜色
    QColor cGroupsBgClr = QColor(255, 85, 127);                //分组背景颜色
    QColor cGroupBorder = QColor(255, 170, 127);               //分组边框颜色

    QColor cLevel1Point = QColor(170, 170, 255);               //数据分级1中心点颜色
    QColor cLevel2Point = QColor(255, 170, 127);               //数据分级2中心点颜色
    QColor cLevel3Point = QColor(255, 85, 127);                //数据分级3中心点颜色
    QColor cLevel4Point = QColor(85, 85, 127);                 //数据分级4中心点颜色

    QColor cLevel1Frame = QColor(255, 85, 127);               //数据分级1中心点边框颜色
    QColor cLevel2Frame = QColor(85, 170, 127);               //数据分级2中心点边框颜色
    QColor cLevel3Frame = QColor(85, 85, 127);                //数据分级3中心点边框颜色
    QColor cLevel4Frame = QColor(170, 170, 255);              //数据分级4中心点边框颜色

    QColor cLevel1Based = QColor(170, 170, 255);              //数据分级1内容背景颜色
    QColor cLevel2Based = QColor(255, 85, 127);               //数据分级2内容背景颜色
    QColor cLevel3Based = QColor(255, 170, 127);              //数据分级3内容背景颜色
    QColor cLevel4Based = QColor(85, 85, 127);                //数据分级4内容背景颜色

    QColor cTagPointClr = QColor(255, 85, 127);               //着重点颜色
    QColor cTagPointClr2 = QColor(170, 170, 255);             //着重点颜色

    bool   bShowDotLine = true;                               //是否显示节点连接线
    double dDotLinesWid = 1.0;                                //节点连接线宽度

    double dLogosRadius = 0.5;                                //Logo圆角比例
    double dLogosBorder = 1;                                  //Logo边框宽度

    QColor cLogosBkgClr = QColor(230,230,230,230);             //Logo背景颜色
    QColor cLogoEdgeClr = QColor(127,127,127,168);            //Logo边框颜色

    uint   uLineSpacing = 12;                                 //行间距

    bool operator==(const QVERTTIMERLINE_DATAS_& rhs)         //操作运算符重载
    {
      return (nItemsMargin == rhs.nItemsMargin)
          && (nItemsHeight == rhs.nItemsHeight)
          && (nInfoPadding == rhs.nInfoPadding)
          && (bFixedRadius == rhs.bFixedRadius)
          && (uFixedRadius == rhs.uFixedRadius)
          && (uTxtRadiusId == rhs.uTxtRadiusId)
          && (uTagRadiusId == rhs.uTagRadiusId)
          && (uGroupRadius == rhs.uGroupRadius)
          && (uTitleRadius == rhs.uTitleRadius)
          && (nInfoHeights == rhs.nInfoHeights)
          && (uAxislyAlign == rhs.uAxislyAlign)
          && (uTimersWidth == rhs.uTimersWidth)
          && (uTxtRadiusId == rhs.uTxtRadiusId)
          && (uStartRadius == rhs.uStartRadius)
          && (uEndlyRadius == rhs.uEndlyRadius)
          && (nPointRadius == rhs.nPointRadius)
          && (cAxislyColor == rhs.cAxislyColor)
          && (cCenterColor == rhs.cCenterColor)
          && (cCenterFrame == rhs.cCenterFrame)
          && (cTitleColors == rhs.cTitleColors)
          && (cTitleBkgClr == rhs.cTitleBkgClr)
          && (cTitleBorder == rhs.cTitleBorder)
          && (cTimeBorders == rhs.cTimeBorders)
          && (cTimeBkgClrs == rhs.cTimeBkgClrs)
          && (cBasedColors == rhs.cBasedColors)
          && (cBorderColor == rhs.cBorderColor)
          && (cTimerColors == rhs.cTimerColors)
          && (cTextsColors == rhs.cTextsColors)
          && (cGroupsColor == rhs.cGroupsColor)
          && (cGroupsBgClr == rhs.cGroupsBgClr)
          && (cGroupBorder == rhs.cGroupBorder)
          && (cLevel1Point == rhs.cLevel1Point)               //数据分级1中心点颜色
          && (cLevel2Point == rhs.cLevel2Point)               //数据分级2中心点颜色
          && (cLevel3Point == rhs.cLevel3Point)                //数据分级3中心点颜色
          && (cLevel4Point == rhs.cLevel4Point)                 //数据分级4中心点颜色
          && (cLevel1Frame == rhs.cLevel1Frame)               //数据分级1中心点边框颜色
          && (cLevel2Frame == rhs.cLevel2Frame)               //数据分级2中心点边框颜色
          && (cLevel3Frame == rhs.cLevel3Frame)                //数据分级3中心点边框颜色
          && (cLevel4Frame == rhs.cLevel4Frame)              //数据分级4中心点边框颜色
          && (cLevel1Based == rhs.cLevel1Based)              //数据分级1内容背景颜色
          && (cLevel2Based == rhs.cLevel2Based)               //数据分级2内容背景颜色
          && (cLevel3Based == rhs.cLevel3Based)              //数据分级3内容背景颜色
          && (cLevel4Based == rhs.cLevel4Based)              //数据分级4内容背景颜色;
          && (cTagPointClr == rhs.cTagPointClr)
          && (cTagPointClr2 == rhs.cTagPointClr2)
          && (bShowDotLine == rhs.bShowDotLine)
          && (dDotLinesWid == rhs.dDotLinesWid)
          && (cLogosBkgClr == rhs.cLogosBkgClr)
          && (cLogoEdgeClr == rhs.cLogoEdgeClr)
          && (uLineSpacing == rhs.uLineSpacing);
    }

    bool operator != (const QVERTTIMERLINE_DATAS_& rhs) // 操作运算符重载
    {
      return !(*this == rhs);
    }
  }QVERTTIMERLINE_DATAS,*PQVERTTIMERLINE_DATAS;

 数据定义代码如下

 //垂直时间线展示项目数据结构
  typedef struct QVERTTIMERLINE_ITEMS_ {
    std::u16string uContentTime;   //时间
    std::u16string uContentDesc;   //信息,最大长度256
    uint           uContentType;   //内容类别,0文字,1图片,2音频,3视频
    std::u16string uContentPath;   //内容路径
    uint           uDatasLevels;   //数据分级 0-4级
    std::u16string uContentUrls;   //内容URL
  }QVERTTIMERLINE_ITEMS,*PQVERTTIMERLINE_ITEMS;

  typedef struct QVERTTIMERLINE_GROUP_ {
    std::u16string                     uGroupsNames;       //分组名称
    QList<QVERTTIMERLINE_ITEMS>        vTimeLineInf;       //数据列表
  }QVERTTIMERLINE_GROUP,*PQVERTTIMERLINE_GROUP;

  //垂直时间线中心数据
  typedef struct QVERTTIMERLINE_TAGS_ {
    QRectF        rcDotInf;               //节点区域
    uint          uStyleId;               //节点风格类型
  }QVERTTIMERLINE_TAGS,*PQVERTTIMERLINE_TAGS;

类定义代码如下

class Lncf_QVTimelineFrm : public QWidget
  {
    Q_OBJECT
  public:
    explicit Lncf_QVTimelineFrm(QWidget *parent = nullptr);
    ~Lncf_QVTimelineFrm();
  protected:
    //系统绘制事件
    void paintEvent(QPaintEvent *);

    /// 绘制标题
    /// \brief DrawTitleValue
    /// \param painter
    ///
    void DrawTitleValue(QPainter *painter);

    /// 绘制时间线项
    /// \brief DrawLinesItems
    /// \param painter
    ///
    void DrawLinesItems(QPainter *painter);

    /// 绘制中心圆点
    /// \brief DrawLineDotInf
    /// \param painter
    ///
    void DrawLineDotInf(QPainter *painter);

    /// 绘制时间点内容
    /// \brief DrawItemsInfos
    /// \param painter
    ///
    void DrawItemsInfos(QPainter *painter);

    /// 绘制分组点内容
    /// \brief DrawItemsGroup
    /// \param painter
    ///
    void DrawItemsGroup(QPainter *painter);

    /// 绘制时间文本
    /// \brief DrawItemsTimer
    /// \param painter
    /// \param rcTime
    /// \param sTime
    ///
    void DrawItemsTimer(QPainter *painter,QRectF rcTime,QString sTime,bool bLeft);

    /// 绘制右侧内容
    /// \brief DrawInfosRight
    /// \param painter
    /// \param infoRect
    /// \param sText
    /// \param sRes
    /// \param sUrl
    /// \param uLineHeight
    /// \param uLevel
    /// \param uType
    ///
    void DrawInfosRight(QPainter *painter,QRectF &infoRect,QString sText,QString sRes,QString sUrl,uint &uLineHeight,uint uLevel,uint uType);

    /// 绘制左侧内容
    /// \brief DrawInfosLefts
    /// \param painter
    /// \param infoRect
    /// \param sText
    /// \param sRes
    /// \param sUrl
    /// \param uLineHeight
    /// \param uLevel
    /// \param uType
    ///
    void DrawInfosLefts(QPainter *painter,QRectF &infoRect,QString sText,QString sRes,QString sUrl,uint &uLineHeight,uint uLevel,uint uType);

    /// 绘制图片Logo
    /// \brief DrawImageLogos
    /// \param painter
    /// \param logoRect  :图像区域
    /// \param sRes      :图片路径
    ///
    void DrawImageLogos(QPainter *painter,QRectF &logoRect,QString sRes);

    /// 绘制音频Logo
    /// \brief DrawAudioLogos
    /// \param painter
    /// \param logoRect  :图像区域
    /// \param sUrl      :音频资源路径
    ///
    void DrawAudioLogos(QPainter *painter,QRectF &logoRect,QString sUrl);

    /// 绘制视频Logo
    /// \brief DrawVideoLogos
    /// \param painter
    /// \param logoRect  :图像区域
    /// \param sRes      :视频封面路径
    /// \param sUrl      :视频资源路径
    ///
    void DrawVideoLogos(QPainter *painter,QRectF &logoRect,QString sRes,QString sUrl);
  public:
    /// 保存图像到文件
    /// \brief SaveTimeLineImg
    /// \param uFilePath   :文件路径
    /// \param uError      :错误信息
    /// \param bTransparent:是否背景透明
    ///
    bool SaveTimeLineImg(std::u16string uFilePath,std::u16string& uError,bool bTransparent = true);
  private:
    //全局配置数据结构体
    QVERTTIMERLINE_DATAS tTimeLineCtlData;

    std::u16string uTitleValues = u"Lncf Qt Vertical timeline";       //标题
    QString        sTitleValues = "Lncf Qt Vertical timeline";        //标题

    std::u16string uImagesPaths;                                      //缺省图片路径
    std::u16string uAudiosPaths;                                      //缺省音频图片路径
    std::u16string uVideosPaths;                                      //缺省视频封面路径

    QFont          fTimeFontObj;                                      //时间字体
    QFont          fTextFontObj;                                      //文字字体
    QFont          fTitlesFonts;                                      //标题字体
    QFont          fGroupsFonts;                                      //分组字体
    uint32_t       uVaxisHeight = 0;                                  //X轴高度
    uint32_t       uTitleHeight;                                      //标题高度

    QList<QVERTTIMERLINE_TAGS>  vDotListInfo;                          //中心点信息
    QList<int>                  vGroupsYvals;                          //分组名称y坐标值

    QList<QVERTTIMERLINE_GROUP> vTimeLineInf;                         //时间线数据链表
  public:
    /// 获取节点风格
    /// \brief GetItemsStyled
    /// \param tStyle
    /// \return
    ///
    QVERTTIMERLINE_DATAS GetItemsStyled() const;

    /// 获取节点边距
    /// \brief GetItemsMargin
    /// \return
    ///
    int GetItemsMargin() const;

    /// 获取节点高度
    /// \brief GetItemsHeight
    /// \return
    ///
    int GetItemsHeight() const;

    /// 获取信息边距
    /// \brief GetInfoPadding
    /// \return
    ///
    int GetInfoPadding() const;

    /// 获取信息高度
    /// \brief GetInfoHeights
    /// \return
    ///
    int GetInfoHeights() const;

    /// 获取基准颜色
    /// \brief GetBasedColors
    /// \return
    ///
    QColor GetBasedColors() const;

    /// 获取线条颜色
    /// \brief GetBorderColor
    /// \return
    ///
    QColor GetBorderColor() const;

    /// 获取轴向对齐方式,0中间,1左侧,2右侧
    /// \brief GetAxislyAlign
    /// \return
    ///
    uint GetAxislyAlign() const;

    /// 获取时间区域宽度
    /// \brief GetTimersWidth
    /// \return
    ///
    uint GetTimersWidth() const;

    /// 获取内容区域边框宽度
    /// \brief GetBorderWidth
    /// \return
    ///
    double GetBorderWidth() const;

    /// 获取文本区域圆角比例
    /// \brief GetTextsRadius
    /// \return
    ///
    double GetTextsRadius() const;

    /// 获取时间区域圆角比例
    /// \brief GetTimerRadius
    /// \return
    ///
    double GetTimerRadius() const;

    /// 获取内容区域圆角风格,0,左下角锐角,1左上角锐角,2右上角锐角,3右下角锐角,4全部圆角,5左侧两个角圆角,6右侧两个角圆角,7上侧两个角圆角,8下侧两个角圆角,9全部锐角,10左下和右上锐角,11左上和右下锐角
    /// \brief GetTxtRidiusId
    /// \return
    ///
    uint GetTxtRidiusId() const;

    /// 获取标题字符串
    /// \brief GetTitleValues
    /// \return
    ///
    QString GetTitleValues() const;

    /// 获取标题宽字符字符串
    /// \brief GetTitleValueW
    /// \return
    ///
    std::u16string GetTitleValueW() const;

    /// 获取时间字体
    /// \brief GetTimeFontObj
    /// \return
    ///
    QFont GetTimeFontObj() const;

    /// 获取文字字体
    /// \brief GetTextFontObj
    /// \return
    ///
    QFont GetTextFontObj() const;

    /// 获取标题字体
    /// \brief GetTitlesFonts
    ///
    QFont GetTitlesFonts() const;

    /// 获取分组字体
    /// \brief GetGroupsFonts
    ///
    QFont GetGroupsFonts() const;

    /

    /// 获取轴宽度
    /// \brief GetAxislyWidth
    /// \return
    ///
    double GetAxislyWidth() const;

    /// 获取标题区域边框宽度
    /// \brief GetBorderTitle
    /// \return
    ///
    double GetBorderTitle() const;

    /// 获取时间区域边框宽度
    /// \brief GetBorderTimer
    /// \return
    ///
    double GetBorderTimer() const;

    /// 获取分组区域边框宽度
    /// \brief GetBorderGroup
    /// \return
    ///
    double GetBorderGroup() const;

    /// 获取分组区域圆角比例
    /// \brief GetGroupRadius
    /// \return
    ///
    double GetGroupRadius() const;

    /// 获取标题区域圆角比例
    /// \brief GetTitleRadius
    /// \return
    ///
    double GetTitleRadius() const;

    /// 获取是否使用固定圆角值
    /// \brief GetFixedStyled
    /// \return
    ///
    bool GetFixedStyled() const;

    /// 获取内容圆角半径绝对值
    /// \brief GetFixedRadius
    /// \return
    ///
    uint GetFixedRadius() const;

    /// 获取时间圆角风格,与内容圆角风格一致
    /// \brief GetTimerStyled
    /// \return
    ///
    uint GetTimerStyled() const;

    /// 获取分组圆角风格,与内容圆角风格一致
    /// \brief GetGroupStyled
    /// \return
    ///
    uint GetGroupStyled() const;

    /// 获取标题圆角风格,与内容圆角风格一致
    /// \brief GetTitleStyled
    /// \return
    ///
    uint GetTitleStyled() const;

    /// 获取开始点半径
    /// \brief GetStartRadius
    /// \return
    ///
    uint GetStartRadius() const;

    /// 获取结束点半径
    /// \brief GetEndlyRadius
    /// \return
    ///
    uint GetEndlyRadius() const;

    /// 获取中心点半径
    /// \brief GetPointRadius
    /// \return
    ///
    int GetPointRadius() const;

    /// 获取轴颜色
    /// \brief GetAxislyColor
    /// \return
    ///
    QColor GetAxislyColor() const;

    /// 获取中心点颜色
    /// \brief GetCenterColor
    /// \return
    ///
    QColor GetCenterColor() const;

    /// 获取中心点边框颜色
    /// \brief GetCenterFrame
    /// \return
    ///
    QColor GetCenterFrame() const;

    /// 获取标题文字颜色
    /// \brief GetTitleColors
    /// \return
    ///
    QColor GetTitleColors() const;

    /// 获取标题背景颜色
    /// \brief GetTitleBkgClr
    /// \return
    ///
    QColor GetTitleBkgClr() const;

    /// 获取标题边框颜色
    /// \brief GetTitleBorder
    /// \return
    ///
    QColor GetTitleBorder() const;

    /// 获取时间边框颜色
    /// \brief GetTimeBorders
    /// \return
    ///
    QColor GetTimeBorders() const;

    /// 获取时间背景颜色
    /// \brief GetTimeBkgClrs
    /// \return
    ///
    QColor GetTimeBkgClrs() const;

    /// 获取时间颜色
    /// \brief GetTimerColors
    /// \return
    ///
    QColor GetTimerColors() const;

    /// 获取文本内容颜色
    /// \brief GetTextsColors
    /// \return
    ///
    QColor GetTextsColors() const;

    /// 获取分组标题颜色
    /// \brief GetGroupsColor
    /// \return
    ///
    QColor GetGroupsColor() const;

    /// 获取分组背景颜色
    /// \brief GetGroupsBgClr
    /// \return
    ///
    QColor GetGroupsBgClr() const;

    /// 获取分组边框颜色
    /// \brief GetGroupBorder
    /// \return
    ///
    QColor GetGroupBorder() const;

    /// 获取数据分级1中心点颜色
    /// \brief GetLevel1Point
    /// \return
    ///
    QColor GetLevel1Point() const;

    /// 获取数据分级2中心点颜色
    /// \brief GetLevel2Point
    /// \return
    ///
    QColor GetLevel2Point() const;

    /// 获取数据分级3中心点颜色
    /// \brief GetLevel3Point
    /// \return
    ///
    QColor GetLevel3Point() const;

    /// 获取数据分级4中心点颜色
    QColor GetLevel4Point() const;

    /// 获取数据分级1中心点边框颜色
    /// \brief GetLevel1Frame
    /// \return
    ///
    QColor GetLevel1Frame() const;

    /// 获取数据分级2中心点边框颜色
    /// \brief GetLevel2Frame
    /// \return
    ///
    QColor GetLevel2Frame() const;

    /// 获取数据分级3中心点边框颜色
    /// \brief GetLevel3Frame
    /// \return
    ///
    QColor GetLevel3Frame() const;

    /// 获取数据分级4中心点边框颜色
    /// \brief GetLevel4Frame
    /// \return
    ///
    QColor GetLevel4Frame() const;

    /// 获取数据分级1内容背景颜色
    /// \brief GetLevel1Based
    /// \return
    ///
    QColor GetLevel1Based() const;

    /// 获取数据分级2内容背景颜色
    /// \brief GetLevel2Based
    /// \return
    ///
    QColor GetLevel2Based() const;

    /// 获取数据分级3内容背景颜色
    /// \brief GetLevel3Based
    /// \return
    ///
    QColor GetLevel3Based() const;

    /// 获取数据分级4内容背景颜色
    /// \brief GetLevel4Based
    /// \return
    ///
    QColor GetLevel4Based() const;

    /// 获取着重点颜色
    /// \brief GetTagPointClr
    /// \return
    ///
    QColor GetTagPointClr() const;

    /// 获取着重点颜色
    /// \brief GetTagPointClr2
    /// \return
    ///
    QColor GetTagPointClr2() const;

    /// 获取是否显示节点连接线
    /// \brief GetShowDotLine
    /// \return
    ///
    bool GetShowDotLine() const;

    /// 获取节点连接线宽度
    /// \brief GetDotLinesWid
    /// \return
    ///
    double GetDotLinesWid() const;

    /// 获取Logo圆角比例
    /// \brief GetLogosRadius
    /// \return
    ///
    double GetLogosRadius() const;

    /// 获取Logo边框宽度
    /// \brief GetLogosBorder
    /// \return
    ///
    double GetLogosBorder() const;

    /// 获取Logo背景颜色
    /// \brief GetLogosBkgClr
    /// \return
    ///
    QColor GetLogosBkgClr() const;

    /// 获取Logo边框颜色
    /// \brief GetLogoEdgeClr
    /// \return
    ///
    QColor GetLogoEdgeClr() const;

    /// 获取行间距
    /// \brief GetLineSpacing
    /// \return
    ///
    uint GetLineSpacing() const;

    /

    /// 获取缺省图片路径
    /// \brief GetImagesPaths
    /// \return
    ///
    std::u16string GetImagesPaths() const;

    /// 获取缺省音频图片路径
    /// \brief GetAudiosPaths
    /// \return
    ///
    std::u16string GetAudiosPaths() const;

    /// 获取缺省视频封面路径
    /// \brief GetVideosPaths
    /// \return
    ///
    std::u16string GetVideosPaths() const;

    /// 获取数据链表
    /// \brief GetTimeLineInf
    /// \return
    ///
    QList<QVERTTIMERLINE_GROUP> GetTimeLineInf() const;

    QSize sizeHint() const;

    QSize minimumSizeHint() const;

  public Q_SLOTS:

    /// 设置时间轴风格
    /// \brief SetItemsStyled
    /// \param tStyle
    ///
    void SetItemsStyled(QVERTTIMERLINE_DATAS tStyle);

    /// 设置节点边距
    /// \brief SetItemsMargin
    /// \param itemMargin
    ///
    void SetItemsMargin(int itemMargin);

    /// 设置节点高度
    /// \brief GetItemsHeight
    /// \param itemHeight
    ///
    void SetItemsHeight(int itemHeight);

    /// 设置信息边距
    /// \brief GetInfoPadding
    /// \param infoPadding
    ///
    void SetInfoPadding(int infoPadding);

    /// 设置信息高度
    /// \brief GetInfoHeights
    /// \param infoHeight
    ///
    void SetInfoHeights(int infoHeight);

    /// 设置基准颜色
    /// \brief GetBasedColors
    /// \param baseColor
    ///
    void SetBasedColors(const QColor &baseColor);

    /// 设置线条颜色
    /// \brief SetBorderColor
    /// \param lineColor
    ///
    void SetBorderColor(const QColor &lineColor);

    /// 设置轴向对齐方式
    /// \brief SetAxislyAlign
    /// \param uValue :0中间,1左侧,2右侧
    ///
    void SetAxislyAlign(const uint &uValue);

    /// 设置时间区域宽度
    /// \brief SetTimersWidth
    /// \param uValue
    ///
    void SetTimersWidth(const uint &uValue);

    /// 设置内容区域边框宽度
    /// \brief SetBorderWidth
    /// \param dValue
    ///
    void SetBorderWidth(const double &dValue);

    /// 设置文本区域圆角比例
    /// \brief SetTextsRadius
    /// \param dValue
    ///
    void SetTextsRadius(const double &dValue);

    /// 设置时间区域圆角比例
    /// \brief SetTimerRadius
    /// \param dValue
    ///
    void SetTimerRadius(const double &dValue);

    /// 设置内容区域圆角风格,0,左下角锐角,1左上角锐角,2右上角锐角,3右下角锐角,4全部圆角,5左侧两个角圆角,6右侧两个角圆角,7上侧两个角圆角,8下侧两个角圆角,9全部锐角,10左下和右上锐角,11左上和右下锐角
    /// \brief SetTxtRidiusId
    /// \param uValue
    ///
    void SetTxtRidiusId(const uint &uValue);

    /// 设置时间字体
    /// \brief SetTimeFontObj
    /// \param fObj
    ///
    void SetTimeFontObj(QFont fObj);

    /// 设置文字字体
    /// \brief SetTextFontObj
    /// \param fObj
    ///
    void SetTextFontObj(QFont fObj);

    /// 设置标题字体
    /// \brief SetTitlesFonts
    /// \param fObj
    /// \return
    ///
    void SetTitlesFonts(QFont fObj);

    /// 设置分组字体
    /// \brief SetGroupsFonts
    /// \param fObj
    /// \return
    ///
    void SetGroupsFonts(QFont fObj);

    /

    /// 设置轴宽度
    /// \brief SetAxislyWidth
    /// \param dValue
    /// \return
    ///
    void SetAxislyWidth(const double& dValue);

    /// 设置标题区域边框宽度
    /// \brief SetBorderTitle
    /// \param dValue
    ///
    void SetBorderTitle(const double& dValue);

    /// 设置时间区域边框宽度
    /// \brief SetBorderTimer
    /// \param dValue
    ///
    void SetBorderTimer(const double& dValue);

    /// 设置分组区域边框宽度
    /// \brief SetBorderGroup
    /// \param dValue
    ///
    void SetBorderGroup(const double& dValue);

    /// 设置分组区域圆角比例
    /// \brief SetGroupRadius
    /// \param dValue
    ///
    void SetGroupRadius(const double& dValue);

    /// 设置标题区域圆角比例
    /// \brief SetTitleRadius
    /// \param dValue
    ///
    void SetTitleRadius(const double& dValue);

    /// 设置是否使用固定圆角值
    /// \brief SetFixedStyled
    /// \param bValue
    ///
    void SetFixedStyled(const bool& bValue);

    /// 设置内容圆角半径绝对值
    /// \brief SetFixedRadius
    /// \param uValue
    ///
    void SetFixedRadius(const uint& uValue);

    /// 设置时间圆角风格,与内容圆角风格一致
    /// \brief SetTimerStyled
    /// \param uValue
    ///
    void SetTimerStyled(const uint& uValue);

    /// 设置分组圆角风格,与内容圆角风格一致
    /// \brief SetGroupStyled
    /// \param uValue
    ///
    void SetGroupStyled(const uint& uValue);

    /// 设置标题圆角风格,与内容圆角风格一致
    /// \brief SetTitleStyled
    /// \param uValue
    ///
    void SetTitleStyled(const uint& uValue);

    /// 设置开始点半径
    /// \brief SetStartRadius
    /// \param uValue
    ///
    void SetStartRadius(const uint& uValue);

    /// 设置结束点半径
    /// \brief SetEndlyRadius
    /// \param uValue
    ///
    void SetEndlyRadius(const uint& uValue);

    /// 设置中心点半径
    /// \brief SetPointRadius
    /// \param nValue
    ///
    void SetPointRadius(const int& nValue);

    /// 设置轴颜色
    /// \brief SetAxislyColor
    /// \param cValue
    ///
    void SetAxislyColor(const QColor& cValue);

    /// 设置中心点颜色
    /// \brief SetCenterColor
    /// \param cValue
    ///
    void SetCenterColor(const QColor& cValue);

    /// 设置中心点边框颜色
    /// \brief SetCenterFrame
    /// \param cValue
    ///
    void SetCenterFrame(const QColor& cValue);

    /// 设置标题文字颜色
    /// \brief SetTitleColors
    /// \param cValue
    ///
    void SetTitleColors(const QColor& cValue);

    /// 设置标题背景颜色
    /// \brief SetTitleBkgClr
    /// \param cValue
    ///
    void SetTitleBkgClr(const QColor& cValue);

    /// 设置标题边框颜色
    /// \brief SetTitleBorder
    /// \param cValue
    ///
    void SetTitleBorder(const QColor& cValue);

    /// 设置时间边框颜色
    /// \brief SetTimeBorders
    /// \param cValue
    ///
    void SetTimeBorders(const QColor& cValue);

    /// 设置时间背景颜色
    /// \brief SetTimeBkgClrs
    /// \param cValue
    ///
    void SetTimeBkgClrs(const QColor& cValue);

    /// 设置时间颜色
    /// \brief SetTimerColors
    /// \param cValue
    ///
    void SetTimerColors(const QColor& cValue);

    /// 设置文本内容颜色
    /// \brief SetTextsColors
    /// \param cValue
    ///
    void SetTextsColors(const QColor& cValue);

    /// 设置分组标题颜色
    /// \brief SetGroupsColor
    /// \param cValue
    ///
    void SetGroupsColor(const QColor& cValue);

    /// 设置分组背景颜色
    /// \brief SetGroupsBgClr
    /// \param cValue
    ///
    void SetGroupsBgClr(const QColor& cValue);

    /// 设置分组边框颜色
    /// \brief SetGroupBorder
    /// \param cValue
    ///
    void SetGroupBorder(const QColor& cValue);

    /// 设置数据分级1中心点颜色
    /// \brief SetLevel1Point
    /// \param cValue
    ///
    void SetLevel1Point(const QColor& cValue);

    /// 设置数据分级2中心点颜色
    /// \brief SetLevel2Point
    /// \param cValue
    ///
    void SetLevel2Point(const QColor& cValue);

    /// 设置数据分级3中心点颜色
    /// \brief SetLevel3Point
    /// \param cValue
    ///
    void SetLevel3Point(const QColor& cValue);

    /// 设置数据分级4中心点颜色
    /// \brief SetLevel4Point
    /// \param cValue
    ///
    void SetLevel4Point(const QColor& cValue);

    /// 设置数据分级1中心点边框颜色
    /// \brief SetLevel1Frame
    /// \param cValue
    ///
    void SetLevel1Frame(const QColor& cValue);

    /// 设置数据分级2中心点边框颜色
    /// \brief SetLevel2Frame
    /// \param cValue
    ///
    void SetLevel2Frame(const QColor& cValue);

    /// 设置数据分级3中心点边框颜色
    /// \brief SetLevel3Frame
    /// \param cValue
    ///
    void SetLevel3Frame(const QColor& cValue);

    /// 设置数据分级4中心点边框颜色
    /// \brief SetLevel4Frame
    /// \param cValue
    ///
    void SetLevel4Frame(const QColor& cValue);

    /// 设置数据分级1内容背景颜色
    /// \brief SetLevel1Based
    /// \param cValue
    ///
    void SetLevel1Based(const QColor& cValue);

    /// 设置数据分级2内容背景颜色
    /// \brief SetLevel2Based
    /// \param cValue
    ///
    void SetLevel2Based(const QColor& cValue);

    /// 设置数据分级3内容背景颜色
    /// \brief SetLevel3Based
    /// \param cValue
    ///
    void SetLevel3Based(const QColor& cValue);

    /// 设置数据分级4内容背景颜色
    /// \brief SetLevel4Based
    /// \param cValue
    ///
    void SetLevel4Based(const QColor& cValue);

    /// 设置着重点颜色
    /// \brief SetTagPointClr
    /// \param cValue
    ///
    void SetTagPointClr(const QColor& cValue);

    /// 设置着重点颜色
    /// \brief SetTagPointClr2
    /// \param cValue
    ///
    void SetTagPointClr2(const QColor& cValue);

    /// 设置是否显示节点连接线
    /// \brief SetShowDotLine
    /// \param bValue
    ///
    void SetShowDotLine(const bool& bValue);

    /// 设置节点连接线宽度
    /// \brief SetDotLinesWid
    /// \param dValue
    ///
    void SetDotLinesWid(const double& dValue);

    /// 设置Logo圆角比例
    /// \brief SetLogosRadius
    /// \param dValue
    ///
    void SetLogosRadius(const double& dValue);

    /// 设置Logo边框宽度
    /// \brief SetLogosBorder
    /// \param dValue
    ///
    void SetLogosBorder(const double& dValue);

    /// 设置Logo背景颜色
    /// \brief SetLogosBkgClr
    /// \param cValue
    ///
    void SetLogosBkgClr(const QColor& cValue);

    /// 设置Logo边框颜色
    /// \brief SetLogoEdgeClr
    /// \param cValue
    ///
    void SetLogoEdgeClr(const QColor& cValue);

    /// 设置行间距
    /// \brief SetLineSpacing
    /// \param uValue
    ///
    void SetLineSpacing(const uint& uValue);

    /

    /// 设置标题
    /// \brief GetTitleValues
    /// \param title
    ///
    void SetTitleValues(const QString &title);

    /// 设置宽字符标题
    /// \brief SetTitleValueW
    /// \param infos
    ///
    void SetTitleValueW(const std::u16string &infos);

    /// 设置信息集合,结构体方式
    /// 此接口将会删除所有已有数据并给与一个未命名分组的时间线数据
    /// \brief SetItemInfList
    /// \param pItems
    ///
    void SetItemInfList(const QList<QVERTTIMERLINE_ITEMS> &pItems);

    /// 追加数据到末端,时间顺序由使用者处理
    /// \brief AddItemInfList
    /// \param pItems
    ///
    void AddItemInfList(QVERTTIMERLINE_GROUP &pItems);

    /// 设置分组数据
    /// 已有的数据会被情况
    /// \brief SetGroupsLists
    /// \param vList
    ///
    void SetGroupsLists(const QList<QVERTTIMERLINE_GROUP> vList);

    /// 设置缺省图片路径
    /// \brief SetImagesPaths
    /// \param infos
    ///
    void SetImagesPaths(const std::u16string &infos);

    /// 设置缺省音频图片路径
    /// \brief SetAudiosPaths
    /// \param infos
    ///
    void SetAudiosPaths(const std::u16string &infos);

    /// 设置缺省视频封面路径
    /// \brief SetVideosPaths
    /// \param infos
    ///
    void SetVideosPaths(const std::u16string &infos);
  };

在最后的使用中将Lncf_QVTimelineFrm添加到一个QScrollArea中既可。

核心绘制代码如下所示

/// 绘制时间线项
  /// \brief DrawLinesItems
  /// \param painter
  ///
  void Lncf_QVTimelineFrm::DrawLinesItems(QPainter *painter)
  {
    painter->save();
    painter->setPen(QPen(tTimeLineCtlData.cAxislyColor, tTimeLineCtlData.dAxislyWidth));
    painter->setBrush(tTimeLineCtlData.cAxislyColor);
    int startY = tTimeLineCtlData.nItemsMargin + (!sTitleValues.isEmpty()?uTitleHeight+tTimeLineCtlData.nItemsMargin:tTimeLineCtlData.nItemsMargin);
    int endY = uVaxisHeight;

    int xValue,yValue;

    //轴向对齐方式,0中间,1左侧,2右侧
    switch (this->tTimeLineCtlData.uAxislyAlign) {
      case 0:
      default:
        xValue = width() / 2.0;
        yValue = width() / 2.0;
        break;
      case 1:
        xValue = tTimeLineCtlData.nItemsMargin+tTimeLineCtlData.uTimersWidth+20;
        yValue = tTimeLineCtlData.nItemsMargin+tTimeLineCtlData.uTimersWidth+20;
        break;
      case 2:
        xValue = width()-tTimeLineCtlData.nItemsMargin-tTimeLineCtlData.uTimersWidth-20;
        yValue = width()-tTimeLineCtlData.nItemsMargin-(tTimeLineCtlData.uTimersWidth+20);
        break;
      }

    painter->drawEllipse(xValue-tTimeLineCtlData.uStartRadius,startY-9,tTimeLineCtlData.uStartRadius*2,tTimeLineCtlData.uStartRadius*2);
    painter->drawLine(xValue, startY, yValue, endY-24);
    painter->setPen(Qt::NoPen);
    painter->setBrush(tTimeLineCtlData.cCenterFrame);
    painter->drawEllipse(xValue-tTimeLineCtlData.uEndlyRadius,endY-(tTimeLineCtlData.uEndlyRadius*2+12),tTimeLineCtlData.uEndlyRadius*2,tTimeLineCtlData.uEndlyRadius*2);
    painter->setBrush(tTimeLineCtlData.cCenterColor);
    painter->drawEllipse(xValue-tTimeLineCtlData.uEndlyRadius+tTimeLineCtlData.uEndlyRadius/2,endY-(tTimeLineCtlData.uEndlyRadius*2+12)+tTimeLineCtlData.uEndlyRadius/2,tTimeLineCtlData.uEndlyRadius,tTimeLineCtlData.uEndlyRadius);
    painter->restore();

    //设置下固定高度
    this->setFixedHeight(uVaxisHeight);
  }

  /// 绘制中心圆点
  /// \brief DrawLineDotInf
  /// \param painter
  ///
  void Lncf_QVTimelineFrm::DrawLineDotInf(QPainter *painter)
  {
    painter->save();
    painter->setPen(Qt::NoPen);
    for(int i=0;i<vDotListInfo.count();i++){
        //绘制垂直线对应的圆
        switch (vDotListInfo[i].uStyleId) {
          case 1:painter->setBrush(tTimeLineCtlData.cLevel1Point); break;
          case 2:painter->setBrush(tTimeLineCtlData.cLevel2Point); break;
          case 3:painter->setBrush(tTimeLineCtlData.cLevel3Point); break;
          case 4:painter->setBrush(tTimeLineCtlData.cLevel3Point); break;
          default:painter->setBrush(tTimeLineCtlData.cCenterColor);break;
          }
        painter->drawEllipse(vDotListInfo[i].rcDotInf);
        switch (vDotListInfo[i].uStyleId) {
          case 1:painter->setBrush(tTimeLineCtlData.cLevel1Frame); break;
          case 2:painter->setBrush(tTimeLineCtlData.cLevel2Frame); break;
          case 3:painter->setBrush(tTimeLineCtlData.cLevel3Frame); break;
          case 4:painter->setBrush(tTimeLineCtlData.cLevel4Frame); break;
          default:painter->setBrush(tTimeLineCtlData.cCenterFrame);break;
          }
        painter->drawEllipse(vDotListInfo[i].rcDotInf.adjusted(tTimeLineCtlData.nPointRadius,tTimeLineCtlData.nPointRadius,-tTimeLineCtlData.nPointRadius,-tTimeLineCtlData.nPointRadius));
      }
    painter->restore();
  }

  /// 绘制时间点内容
  /// \brief DrawItemsInfos
  /// \param painter
  ///
  void Lncf_QVTimelineFrm::DrawItemsInfos(QPainter *painter)
  {
    painter->save();
    painter->setPen(Qt::NoPen);

    uint uLineHeight = !sTitleValues.isEmpty()?tTimeLineCtlData.nItemsHeight:2;
    vDotListInfo.clear();
    vGroupsYvals.clear();
    int startY = tTimeLineCtlData.nItemsMargin+uTitleHeight+tTimeLineCtlData.uStartRadius*2+16;

    //追个绘制时间轴信息集合,偶数行左侧绘制时间右侧绘制信息
    for (int i = 0; i < vTimeLineInf.size(); i++) {
        vGroupsYvals.push_back(startY);
        startY += tTimeLineCtlData.nItemsHeight+tTimeLineCtlData.uLineSpacing;

        if(vTimeLineInf[i].uGroupsNames.empty())
          vTimeLineInf[i].uGroupsNames = QString("Unnamed Group %1").arg(i).toStdU16String();

        for(int x =0;x<vTimeLineInf[i].vTimeLineInf.size();x++){

            std::u16string sContent = vTimeLineInf[i].vTimeLineInf.at(x).uContentDesc;
            if(sContent.length()>256)
              sContent = sContent.substr(0,256);

            //轴向对齐方式,0中间,1左侧,2右侧
            switch (this->tTimeLineCtlData.uAxislyAlign) {
              default:
              case 0:{
                  int centerX = this->width() / 2.0;
                  int spacer = tTimeLineCtlData.nItemsMargin + 10;

                  if (x % 2 == 0) {
                      //绘制时间
                      QRectF textRect(centerX - spacer-tTimeLineCtlData.uTimersWidth, startY, tTimeLineCtlData.uTimersWidth, tTimeLineCtlData.nItemsHeight);
                      DrawItemsTimer(painter,textRect,QString::fromStdU16String(vTimeLineInf[i].vTimeLineInf.at(x).uContentTime),true);

                      //绘制右侧信息
                      QRectF infoRect(centerX + spacer+tTimeLineCtlData.nItemsMargin/2, textRect.center().y() - tTimeLineCtlData.nItemsHeight/2, centerX - spacer - tTimeLineCtlData.nItemsMargin - tTimeLineCtlData.nItemsHeight / 2.0, tTimeLineCtlData.nItemsHeight);
                      DrawInfosRight(painter,infoRect,QString::fromStdU16String(sContent),QString::fromStdU16String(vTimeLineInf[i].vTimeLineInf.at(x).uContentPath)
                                     ,QString::fromStdU16String(vTimeLineInf[i].vTimeLineInf.at(x).uContentUrls),uLineHeight,vTimeLineInf[i].vTimeLineInf.at(x).uDatasLevels,vTimeLineInf[i].vTimeLineInf.at(x).uContentType);
                    } else {
                      //绘制时间
                      QRectF textRect(centerX + spacer, startY, tTimeLineCtlData.uTimersWidth, tTimeLineCtlData.nItemsHeight);
                      DrawItemsTimer(painter,textRect,QString::fromStdU16String(vTimeLineInf[i].vTimeLineInf.at(x).uContentTime),false);

                      //绘制左侧信息
                      QRectF infoRect(tTimeLineCtlData.nItemsMargin + tTimeLineCtlData.nInfoHeights / 2.0, textRect.center().y() - tTimeLineCtlData.nItemsHeight/2, centerX - spacer - tTimeLineCtlData.nItemsMargin - tTimeLineCtlData.nItemsHeight / 2.0, tTimeLineCtlData.nItemsHeight);
                      DrawInfosLefts(painter,infoRect,QString::fromStdU16String(sContent),QString::fromStdU16String(vTimeLineInf[i].vTimeLineInf.at(x).uContentPath)
                                     ,QString::fromStdU16String(vTimeLineInf[i].vTimeLineInf.at(x).uContentUrls),uLineHeight,vTimeLineInf[i].vTimeLineInf.at(x).uDatasLevels,vTimeLineInf[i].vTimeLineInf.at(x).uContentType);
                    }
                  QVERTTIMERLINE_TAGS tagDotInf;
                  tagDotInf.rcDotInf=QRectF(centerX - 12, startY + 12, 24, 24);
                  tagDotInf.uStyleId = vTimeLineInf[i].vTimeLineInf.at(x).uDatasLevels;
                  vDotListInfo.push_back(tagDotInf);
                }break;
              case 1:{
                  //绘制时间
                  QRectF textRect(tTimeLineCtlData.nItemsMargin, startY, tTimeLineCtlData.uTimersWidth, tTimeLineCtlData.nItemsHeight);
                  DrawItemsTimer(painter,textRect,QString::fromStdU16String(vTimeLineInf[i].vTimeLineInf.at(x).uContentTime),true);

                  //绘制右侧信息
                  QRectF infoRect(tTimeLineCtlData.nItemsMargin+tTimeLineCtlData.uTimersWidth+40+tTimeLineCtlData.nItemsMargin, textRect.center().y() - tTimeLineCtlData.nItemsHeight/2, this->rect().width()-(tTimeLineCtlData.nItemsMargin+tTimeLineCtlData.uTimersWidth+60+tTimeLineCtlData.nItemsMargin), tTimeLineCtlData.nItemsHeight);
                  DrawInfosRight(painter,infoRect,QString::fromStdU16String(sContent),QString::fromStdU16String(vTimeLineInf[i].vTimeLineInf.at(x).uContentPath)
                                 ,QString::fromStdU16String(vTimeLineInf[i].vTimeLineInf.at(x).uContentUrls),uLineHeight,vTimeLineInf[i].vTimeLineInf.at(x).uDatasLevels,vTimeLineInf[i].vTimeLineInf.at(x).uContentType);

                  QVERTTIMERLINE_TAGS tagDotInf;
                  tagDotInf.rcDotInf=QRectF(tTimeLineCtlData.nItemsMargin+tTimeLineCtlData.uTimersWidth+8, startY + 12, 24, 24);
                  tagDotInf.uStyleId = vTimeLineInf[i].vTimeLineInf.at(x).uDatasLevels;
                  vDotListInfo.push_back(tagDotInf);
                }break;
              case 2:{

                  //painter->drawLine(width()-tTimeLineCtlData.nItemsMargin-tTimeLineCtlData.uTimersWidth-20, startY, width()-tTimeLineCtlData.nItemsMargin-(tTimeLineCtlData.uTimersWidth+20), endY);

                  //绘制时间
                  QRectF textRect(this->rect().right()-tTimeLineCtlData.nItemsMargin-tTimeLineCtlData.uTimersWidth, startY, tTimeLineCtlData.uTimersWidth, tTimeLineCtlData.nItemsHeight);
                  DrawItemsTimer(painter,textRect,QString::fromStdU16String(vTimeLineInf[i].vTimeLineInf.at(x).uContentTime),false);

                  //绘制右侧信息
                  QRectF infoRect(this->rect().left()+tTimeLineCtlData.nItemsMargin*2, textRect.center().y() - tTimeLineCtlData.nItemsHeight/2, this->rect().width()-(tTimeLineCtlData.nItemsMargin+tTimeLineCtlData.uTimersWidth+60+tTimeLineCtlData.nItemsMargin), tTimeLineCtlData.nItemsHeight);
                  DrawInfosLefts(painter,infoRect,QString::fromStdU16String(sContent),QString::fromStdU16String(vTimeLineInf[i].vTimeLineInf.at(x).uContentPath)
                                 ,QString::fromStdU16String(vTimeLineInf[i].vTimeLineInf.at(x).uContentUrls),uLineHeight,vTimeLineInf[i].vTimeLineInf.at(x).uDatasLevels,vTimeLineInf[i].vTimeLineInf.at(x).uContentType);

                  QVERTTIMERLINE_TAGS tagDotInf;
                  tagDotInf.rcDotInf=QRectF(textRect.left()-tTimeLineCtlData.nItemsMargin-21, startY + 12, 24, 24);
                  tagDotInf.uStyleId = vTimeLineInf[i].vTimeLineInf.at(x).uDatasLevels;
                  vDotListInfo.push_back(tagDotInf);
                }break;
              }

            startY += uLineHeight;
          }
      }
    painter->restore();
    //设置下固定高度
    uVaxisHeight = startY+tTimeLineCtlData.uEndlyRadius*2;
    //this->setFixedHeight(startY + uLineHeight+20);
  }

至此垂直时间线控件基本就完成了,根据上面的代码您可以自定义实现辅助函数从而实现一个垂直时间线控件,自己在完成属性接口与信号连接即可使用

有关技术分享和控件以及商业合作交流请加QQ群:717743458。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 基于Qt复杂流程图件设计与实现包括以下几个方面。 首先,设计数据结构存储流程图的信息。可以使用节点和连接两种基本对象来表示流程图。节点保存节点类型、位置、大小以及其他自定义属性。连接保存连接的起始节点、终止节点以及其他自定义属性。 其次,设计绘图件并实现绘图功能。可以使用Qt的绘图类来绘制节点和连接。通过重写绘图事件函数,可以在件中绘制节点的图形、标签和其他自定义内容。 然后,实现节点和连接的编辑功能。可以通过鼠标交互实现节点和连接的拖拽、调整大小、删除等操作。可以使用鼠标事件和几何计算来实现这些功能。 接下来,实现流程图的布局和自动调整功能。可以采用拖拽布局、栅格布局等方法来调整节点的位置和连接的路径,使流程图看起来更加美观和整齐。 最后,实现流程图的数据交互和保存功能。可以使用信号和槽机制来实现节点和连接的交互。可以使用XML或JSON等格式将流程图保存为文件,并能够读取和加载已保存的流程图。 综上所述,基于Qt复杂流程图件的设计和实现需要涉及数据结构、绘图、交互、布局以及数据保存等方面的技术。通过合理组织和实现这些技术,可以实现一个功能强大、易用且美观的流程图件。 ### 回答2: 基于Qt复杂流程图件设计与实现涉及以下几个关键步骤。 首先,需要设计流程图件的外观和功能。可以考虑流程节点、线条样式、标签显示等方面的设计。可以使用Qt提供的图形引擎和绘制函数,结合自定义的绘制函数,来实现流程图件的外观设计。 接下来,需要定义流程节点和线条的数据结构。考虑到复杂流程图可能包含多种类型的节点和线条,可以使用继承的方式来定义不同类型的节点和线条类,以便于对它们进行管理和渲染。同时,可以定义属性和方法来保存和处理节点和线条的相关信息。 然后,需要实现流程节点和线条的创建与连接功能。可以通过鼠标事件来捕获用户的交互操作,创建新的节点或者连接已有节点。可以使用容器来保存所有的节点和线条对象,并实现对它们的增加、删除、查找等操作。 接下来,需要实现流程节点和线条的编辑功能。可以考虑对节点和线条的拖拽、缩放、旋转、改变样式等支持,来满足用户对流程图的编辑需求。可以通过重载事件处理函数和绘制函数,来实现这些编辑功能。 最后,可以考虑加入其他的辅助功能,如撤销、重做、导出图像、导入图像等。可以使用Qt提供的信号和槽机制,来实现这些辅助功能,提升流程图件的易用性和灵活性。 总的来说,基于Qt复杂流程图件的设计与实现需要考虑外观设计、数据结构设计、节点和线条的创建与连接、编辑功能的实现以及其他辅助功能的加入。通过合理的设计和实现,可以满足用户对复杂流程图的需求,并提供良好的用户体验。 ### 回答3: 基于Qt复杂流程图件的设计与实现需要考虑以下几个关键方面。 首先,需要设计可扩展的图形模型。通过定义节点、连接线等基本图元的数据结构,可以构建起流程图的数据模型。同时,还需要考虑节点属性、连接线的起始节点和目标节点、节点间的运行顺序等概念。 其次,需要设计绘图逻辑。利用Qt的绘图功能,可以根据图形模型中定义的节点和连接线信息,将它们绘制到件上。可以使用QPainter类进行绘图操作,按照节点和连接线的位置、样式等进行绘制。 进一步,需要实现节点和连接线交互功能。通过捕捉鼠标事件或者键盘事件,可以实现节点的拖动、缩放、旋转等功能。同时,还可以实现选中、高亮和变色等交互效果,提升用户体验。 另外,需要实现流程图的布局算法。对于复杂的流程图,自动布局是必要的。可以采用层次布局、树形布局等算法,确保节点和连接线件中合理排列,并避免节点之间的重叠和遮挡。 最后,还可以考虑添加一些附加功能,例如撤销/重做、导入/导出、文本编辑等。这些功能可以增强流程图件的实用性。 总之,基于Qt复杂流程图件的设计与实现需要通过数据模型、绘图逻辑、交互功能、布局算法等多个方面的设计来完成。通过合理的架构和优化性能的实现方式,可以实现一个功能完备、易用的流程图件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值