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

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

基于QListView,功能相当强大,支持所有鼠标事件,包括悬停,单击,所有按钮均支持单击悬停,支持触控滚动,支持右击功能。描述和标题区域均可隐藏,时间线标题与分组均可隐藏 参考下图

列表风格定义代码如下

///
/// 垂直时间线列表风格数据结构
///
typedef struct QTIMELINELIST_STYLE_ {
    double    dCoveresRadius = 0.5;                       //封面图像半径,如果为0则为矩形,最大不能大于0.5,当为0.5时显示圆形
    double    vLeftBkgRadius[4] = { 24,24,0,24 };           //左上,左下,右上,右下,左侧项目边框圆角半径,最大不能大于1,当为0.5时显示圆形
    double    vRighBkgRadius[4] = { 0,24,24,24 };           //左上,左下,右上,右下,右侧项目边框圆角半径,最大不能大于1,当为0.5时显示圆形
    double    dOptBtnsRadius = 0.5;                       //选项按钮圆角比例,如果为0则为矩形,最大不能大于0.5,当为0.5时显示圆形,选项按钮包含点赞,反对,评论,喜欢,收藏,删除,编辑,编辑位于时间线中轴
    double    vTitlelyRadius[4] = { 0.5,0.5,0.5,0.5 };      //标题圆角比例,左上,左下,右上,右下,最大不能大于1,当为0.5时显示圆形
    double    vGrouplyRadius[4] = { 0.5,0.5,0.5,0.5 };      //分组圆角比例,左上,左下,右上,右下,最大不能大于1,当为0.5时显示圆形
    double    vTimeRadiusVal[4] = { 0.5,0.5,0.5,0.5 };      //时间圆角比例,左上,左下,右上,右下,最大不能大于1,当为0.5时显示圆形
    double    dTagInfoRadius = 0.5;

    double    dTitleFrmWidth = 1.0;
    double    dGroupFrmWidth = 1.0;
    double    dOptbnFrmWidth = 0;
    double    dEdtbnFrmWidth = 2;
    double    dBodyFrmWidths = 4.0;
    double    dNodeFrmWidths = 4.0;
    double    dTimeFrmWidths = 1.0;

    QColor    cTitleBkgColor = QColor(0, 170, 100);         //标题背景色
    QColor    cTitleBkgHover = QColor(255, 85, 127);        //标题背景鼠标悬停颜色
    QColor    cTitleFrmColor = QColor(0, 144, 85);          //标题边框色
    QColor    cTitleFrmHover = QColor(255, 64, 100);        //标题边框鼠标悬停颜色
    QColor    cTitleTxtColor = QColor(255, 255, 255);       //标题文本颜色
    QColor    cTitleTxtHover = QColor(255, 255, 255);       //标题文本鼠标悬停颜色

    QColor    cGroupBkgColor = QColor(255, 192, 120);       //分组背景色
    QColor    cGroupBkgHover = QColor(255, 85, 127);        //分组背景鼠标悬停颜色
    QColor    cGroupFrmColor = QColor(0, 144, 85);          //分组边框色
    QColor    cGroupFrmHover = QColor(255, 64, 100);        //分组边框鼠标悬停颜色
    QColor    cGroupTxtColor = QColor(255, 255, 255);       //分组文本颜色
    QColor    cGroupTxtHover = QColor(255, 255, 255);       //分组文本鼠标悬停颜色

    QColor    cLeftItemColor = QColor(138, 144, 179);          //左侧正文背景色
    QColor    cLeftItemHover = QColor(255, 85, 127);         //左侧正文鼠标悬停背景色
    QColor    cLeftFrameClrs = QColor(255, 64, 100);        //左侧正文边框颜色
    QColor    cLeftFrmHovers = QColor(255, 64, 100);        //左侧正文边框鼠标悬停颜色
    QColor    cLeftNamesClrs = QColor(238, 238, 238);       //左侧正文标题颜色
    QColor    cLeftNameHover = QColor(255, 255, 255);       //左侧正文标题鼠标悬停颜色
    QColor    cLeftTextColor = QColor(238, 238, 238);       //左侧正文文本颜色
    QColor    cLeftTextHover = QColor(255, 255, 255);       //左侧正文文本鼠标悬停颜色

    QColor    cRighItemColor = QColor(96, 168, 145);          //右侧正文背景色
    QColor    cRighItemHover = QColor(255, 85, 127);         //右侧正文鼠标悬停背景色
    QColor    cRighFrameClrs = QColor(255, 64, 100);        //左侧正文边框颜色
    QColor    cRighFrmHovers = QColor(255, 64, 100);        //左侧正文边框鼠标悬停颜色
    QColor    cRighNamesClrs = QColor(238, 238, 238);       //右侧正文背景色
    QColor    cRighNameHover = QColor(255, 255, 255);       //右侧正文标题颜色
    QColor    cRighTextColor = QColor(238, 238, 238);       //右侧正文文本颜色
    QColor    cRighTextHover = QColor(255, 255, 255);       //右侧正文文本鼠标悬停颜色

    QColor    cEdtBnBkgColor = QColor(165, 179, 238);       //编辑按钮背景色
    QColor    cEdtBnBkgHover = QColor(249, 108, 53);       //编辑按钮鼠标悬停背景色
    QColor    cEdtBnBgSelect = QColor(128, 132, 255);       //编辑按钮选中背景色
    QColor    cEdtBnFrmColor = QColor(249, 109, 40);       //编辑按钮边框颜色
    QColor    cEdtBnFrmHover = QColor(249, 108, 53);       //编辑按钮鼠标悬停边框颜色
    QColor    cEdtFrmsSelect = QColor(128, 132, 255);       //编辑按钮选中边框颜色

    QColor    cOptBnBkgColor = QColor(192, 192, 192, 168);   //选项按钮背景色
    QColor    cOptBnBkgHover = QColor(0, 170, 144);         //选项按钮鼠标悬停颜色
    QColor    cOptBnBgSelect = QColor(115, 110, 215);       //选项按钮选中颜色
    QColor    cOptBnFrmColor = QColor(192, 192, 192, 168);   //选项按钮边框颜色
    QColor    cOptBnFrmHover = QColor(0, 170, 144);       //选项按钮鼠标悬停边框颜色
    QColor    cOptFrmsSelect = QColor(115, 110, 215);       //选项按钮选中边框颜色

    QColor    cNodeBkgColors = QColor(238, 238, 238);       //连接节点背景色
    QColor    cNodeFrmColors = QColor(249, 109, 40);       //连接节点边框颜色

    QColor    cOptTagBkgClrs = QColor(255, 85, 127);        //选项标识背景颜色
    QColor    cOptTagTxtClrs = QColor(238, 238, 238);       //选项标识文本颜色

    QColor    cTimerBkgColor = QColor(127, 85, 170, 127);    //选项标识背景颜色
    QColor    cTimerTxtColor = QColor(255, 255, 255);       //选项标识文本颜色
    QColor    cTimerFrmColor = QColor(127, 85, 170);        //选项标识文本颜色

    QColor    cLinkTextColor = QColor(238, 238, 238);       //链接按钮文本颜色
    QColor    cLinkTextHover = QColor(255, 255, 255);       //链接按钮文本鼠标悬停时颜色
    QColor    cLinkTxtSelect = QColor(255, 255, 255);       //连接按钮文本选中时颜色

    QColor    cSplitLineHClr = QColor(249, 109, 40);        //水平线颜色
    QColor    cSplitLineVClr = QColor(249, 109, 40);        //垂直线颜色
    QColor    cItemsCoverBkg = QColor(88, 88, 88, 200);      //封面背景色
    QColor    cCoverHoverBkg = QColor(249, 109, 40, 127);    //封面鼠标悬停背景色

    QColor    cTitleLineClrs = QColor(248, 248, 248, 66);    //标题底线颜色
    QColor    cDescLineColor = QColor(248, 248, 248, 66);    //描述底线颜色
    QColor    cBodyTitlesBkg = QColor(248, 248, 248, 33);    //标题背景色
    QColor    cBodyDescBkgnd = QColor(55, 55, 69, 33);       //描述背景色
    QColor    cDescInfTxtClr = QColor(200, 200, 200);       //描述文字颜色

    QColor    cHelpUrlTxtClr = QColor(160, 190, 255);         //帮助链接文字颜色
    QColor    cHelpUrlHovers = QColor(255, 127, 0);         //鼠标悬停时帮助链接文字颜色

    double    dSplitLineHWid = 1;                         //水平线宽度
    double    dTitileLineWid = 0.5;                       //标题底线宽度
    double    dDescLineWidth = 0.5;                       //描述底线宽度
    double    dSplitLineVWid = 2;                         //垂直线宽度

    uint      uTitlesHeights = 36;                        //标题高度
    uint      uGroupsHeights = 30;                        //分组高度
    uint      uCoverWidthVal = 100;                       //封面宽度
    uint      uTitlePaddingH = 10;                        //标题水平内边距
    uint      uGroupPaddingH = 10;                        //分组水平内边距
    uint      uTitlesMarginV = 6;                        //标题水平外边距
    uint      uGroupsMarginV = 6;                        //分组水平外边距

    uint      uMidBtnsWidths = 32;                        //中间按钮大小
    int       nMidIconOffset = 7;                         //中间按钮图标相对于按钮尺寸边距偏移
    uint      uOptBtnsWidths = 28;                        //选项按钮大小
    int       nOptIconOffset = 6;                         //选项图标相对于按钮尺寸边距偏移
    uint      uNodeBtnsWidth = 28;                        //节点标识大小

    int       nItemMarginVal = 3;                         //边距
    uint      nSplitLineType = 0;                         //连接线样式,0实线,1虚线,2点线,3点划线,4双点划线
    uint      uMiniHeightVal = 48;                        //最低行高
    bool      bGrayCoversImg = false;                     //是否显示灰度图像
    int       nVerticMargins = 6;                         //垂直边距
    int       nLeftMarginVal = 15;                        //左边距
    int       nRighMarginVal = 15;                        //右边距
    uint      uBodySpaceVals = 6;                         //正文间距
    uint      uItemSpaceVals = 6;                         //项目间距
    uint      uBodysPaddings = 6;                         //正文边距

    bool operator == (const QTIMELINELIST_STYLE_& rhs) // 操作运算符重载
    {
        return (DoubleValuesComp(dCoveresRadius, rhs.dCoveresRadius))
               && (DoubleValuesComp(dOptBtnsRadius, rhs.dOptBtnsRadius))
               && (DoubleValuesComp(vLeftBkgRadius[0], rhs.vLeftBkgRadius[0]))
               && (DoubleValuesComp(vLeftBkgRadius[1], rhs.vLeftBkgRadius[1]))
               && (DoubleValuesComp(vLeftBkgRadius[2], rhs.vLeftBkgRadius[2]))
               && (DoubleValuesComp(vLeftBkgRadius[3], rhs.vLeftBkgRadius[3]))
               && (DoubleValuesComp(vRighBkgRadius[0], rhs.vRighBkgRadius[0]))
               && (DoubleValuesComp(vRighBkgRadius[1], rhs.vRighBkgRadius[1]))
               && (DoubleValuesComp(vRighBkgRadius[2], rhs.vRighBkgRadius[2]))
               && (DoubleValuesComp(vRighBkgRadius[3], rhs.vRighBkgRadius[3]))
               && (DoubleValuesComp(vTitlelyRadius[0], rhs.vTitlelyRadius[0]))
               && (DoubleValuesComp(vTitlelyRadius[1], rhs.vTitlelyRadius[1]))
               && (DoubleValuesComp(vTitlelyRadius[2], rhs.vTitlelyRadius[2]))
               && (DoubleValuesComp(vTitlelyRadius[3], rhs.vTitlelyRadius[3]))
               && (DoubleValuesComp(vGrouplyRadius[0], rhs.vGrouplyRadius[0]))
               && (DoubleValuesComp(vGrouplyRadius[1], rhs.vGrouplyRadius[1]))
               && (DoubleValuesComp(vGrouplyRadius[2], rhs.vGrouplyRadius[2]))
               && (DoubleValuesComp(vGrouplyRadius[3], rhs.vGrouplyRadius[3]))
               && (DoubleValuesComp(vTimeRadiusVal[0], rhs.vTimeRadiusVal[0]))
               && (DoubleValuesComp(vTimeRadiusVal[1], rhs.vTimeRadiusVal[1]))
               && (DoubleValuesComp(vTimeRadiusVal[2], rhs.vTimeRadiusVal[2]))
               && (DoubleValuesComp(vTimeRadiusVal[3], rhs.vTimeRadiusVal[3]))
               && (DoubleValuesComp(dTagInfoRadius, rhs.dTagInfoRadius))
               && (DoubleValuesComp(dTitleFrmWidth, rhs.dTitleFrmWidth))
               && (DoubleValuesComp(dGroupFrmWidth, rhs.dGroupFrmWidth))
               && (DoubleValuesComp(dOptbnFrmWidth, rhs.dOptbnFrmWidth))
               && (DoubleValuesComp(dEdtbnFrmWidth, rhs.dEdtbnFrmWidth))
               && (DoubleValuesComp(dBodyFrmWidths, rhs.dBodyFrmWidths))
               && (DoubleValuesComp(dNodeFrmWidths, rhs.dNodeFrmWidths))
               && (DoubleValuesComp(dTimeFrmWidths, rhs.dTimeFrmWidths))
               && (DoubleValuesComp(dSplitLineHWid, rhs.dSplitLineHWid))
               && (DoubleValuesComp(dTitileLineWid, rhs.dTitileLineWid))
               && (DoubleValuesComp(dDescLineWidth, rhs.dDescLineWidth))
               && (DoubleValuesComp(dSplitLineVWid, rhs.dSplitLineVWid))
               && (cTitleBkgColor == rhs.cTitleBkgColor)
               && (cTitleBkgHover == rhs.cTitleBkgHover)
               && (cTitleFrmColor == rhs.cTitleFrmColor)
               && (cTitleFrmHover == rhs.cTitleFrmHover)
               && (cTitleTxtColor == rhs.cTitleTxtColor)
               && (cTitleTxtHover == rhs.cTitleTxtHover)
               && (cGroupBkgColor == rhs.cGroupBkgColor)
               && (cGroupBkgHover == rhs.cGroupBkgHover)
               && (cGroupFrmColor == rhs.cGroupFrmColor)
               && (cGroupFrmHover == rhs.cGroupFrmHover)
               && (cGroupTxtColor == rhs.cGroupTxtColor)
               && (cGroupTxtHover == rhs.cGroupTxtHover)
               && (cLeftItemColor == rhs.cLeftItemColor)
               && (cLeftItemHover == rhs.cLeftItemHover)
               && (cLeftFrameClrs == rhs.cLeftFrameClrs)
               && (cLeftFrmHovers == rhs.cLeftFrmHovers)
               && (cLeftNamesClrs == rhs.cLeftNamesClrs)
               && (cLeftNameHover == rhs.cLeftNameHover)
               && (cLeftTextColor == rhs.cLeftTextColor)
               && (cLeftTextHover == rhs.cLeftTextHover)
               && (cRighItemColor == rhs.cRighItemColor)
               && (cRighItemHover == rhs.cRighItemHover)
               && (cRighFrameClrs == rhs.cRighFrameClrs)
               && (cRighFrmHovers == rhs.cRighFrmHovers)
               && (cRighNamesClrs == rhs.cRighNamesClrs)
               && (cRighNameHover == rhs.cRighNameHover)
               && (cRighTextColor == rhs.cRighTextColor)
               && (cRighTextHover == rhs.cRighTextHover)
               && (cEdtBnBkgColor == rhs.cEdtBnBkgColor)
               && (cEdtBnBkgHover == rhs.cEdtBnBkgHover)
               && (cEdtBnBgSelect == rhs.cEdtBnBgSelect)
               && (cEdtBnFrmColor == rhs.cEdtBnFrmColor)
               && (cEdtBnFrmHover == rhs.cEdtBnFrmHover)
               && (cEdtFrmsSelect == rhs.cEdtFrmsSelect)
               && (cOptBnBkgColor == rhs.cOptBnBkgColor)
               && (cOptBnBkgHover == rhs.cOptBnBkgHover)
               && (cOptBnBgSelect == rhs.cOptBnBgSelect)
               && (cOptBnFrmColor == rhs.cOptBnFrmColor)
               && (cOptBnFrmHover == rhs.cOptBnFrmHover)
               && (cOptFrmsSelect == rhs.cOptFrmsSelect)
               && (cNodeBkgColors == rhs.cNodeBkgColors)
               && (cNodeFrmColors == rhs.cNodeFrmColors)
               && (cOptTagBkgClrs == rhs.cOptTagBkgClrs)
               && (cOptTagTxtClrs == rhs.cOptTagTxtClrs)
               && (cTimerBkgColor == rhs.cTimerBkgColor)
               && (cTimerTxtColor == rhs.cTimerTxtColor)
               && (cTimerFrmColor == rhs.cTimerFrmColor)
               && (cLinkTextColor == rhs.cLinkTextColor)
               && (cLinkTextHover == rhs.cLinkTextHover)
               && (cLinkTxtSelect == rhs.cLinkTxtSelect)
               && (cSplitLineHClr == rhs.cSplitLineHClr)
               && (cSplitLineVClr == rhs.cSplitLineVClr)
               && (cItemsCoverBkg == rhs.cItemsCoverBkg)
               && (cCoverHoverBkg == rhs.cCoverHoverBkg)
               && (cTitleLineClrs == rhs.cTitleLineClrs)
               && (cDescLineColor == rhs.cDescLineColor)
               && (cBodyTitlesBkg == rhs.cBodyTitlesBkg)
               && (cBodyDescBkgnd == rhs.cBodyDescBkgnd)
               && (cDescInfTxtClr == rhs.cDescInfTxtClr)
               && (cHelpUrlTxtClr == rhs.cHelpUrlTxtClr)
               && (cHelpUrlHovers == rhs.cHelpUrlHovers)
               && (uTitlesHeights == rhs.uTitlesHeights)
               && (uGroupsHeights == rhs.uGroupsHeights)
               && (uCoverWidthVal == rhs.uCoverWidthVal)
               && (uTitlePaddingH == rhs.uTitlePaddingH)
               && (uGroupPaddingH == rhs.uGroupPaddingH)
               && (uTitlesMarginV == rhs.uTitlesMarginV)
               && (uGroupsMarginV == rhs.uGroupsMarginV)
               && (uMidBtnsWidths == rhs.uMidBtnsWidths)
               && (nMidIconOffset == rhs.nMidIconOffset)
               && (uOptBtnsWidths == rhs.uOptBtnsWidths)
               && (nOptIconOffset == rhs.nOptIconOffset)
               && (uNodeBtnsWidth == rhs.uNodeBtnsWidth)
               && (nItemMarginVal == rhs.nItemMarginVal)
               && (nSplitLineType == rhs.nSplitLineType)
               && (uMiniHeightVal == rhs.uMiniHeightVal)
               && (bGrayCoversImg == rhs.bGrayCoversImg)
               && (nVerticMargins == rhs.nVerticMargins)
               && (nLeftMarginVal == rhs.nLeftMarginVal)
               && (nRighMarginVal == rhs.nRighMarginVal)
               && (uBodySpaceVals == rhs.uBodySpaceVals)
               && (uItemSpaceVals == rhs.uItemSpaceVals)
               && (uBodysPaddings == rhs.uBodysPaddings);
    }

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

通过上述代码可以看出风格自定义范围非常广泛,下面是Item选项按钮数据结构体定义代码

/// 时间线选项按钮属性
typedef struct QTIMELINELIST_OPTBN_{
    uint           uButtonsIndexs = 0;                     //选项按钮索引
    std::u16string sButtonIcoPath;                         //选项按钮图标位置
    std::u16string sBtnSelectIcon;                         //选中时图标位置
    QImage         pButtonIconObj;                         //选项按钮图标位置
    QImage         pBtnSelectObjs;                         //选中时图标位置
    std::u16string sButtonTextVal;                         //选项按钮文本
    std::u16string sButtonTipsVal;                         //选项按钮提示信息
    bool           bSupportSelect = false;                 //是否支持选中
    bool           bSupportTagVal = true;                  //是否支持tag信息

    bool operator == (const QTIMELINELIST_OPTBN_& rhs) // 操作运算符重载
    {
        return (uButtonsIndexs == rhs.uButtonsIndexs)
               && (sButtonIcoPath == rhs.sButtonIcoPath)          //是否显示选项按钮
               && (sBtnSelectIcon == rhs.sBtnSelectIcon)          //选中时图标位置
               && (sButtonTextVal == rhs.sButtonTextVal)          //字体大小
               && (sButtonTipsVal == rhs.sButtonTipsVal)          //选项按钮提示信息
               && (bSupportSelect == rhs.bSupportSelect)          //是否支持选中
               && (bSupportTagVal == rhs.bSupportTagVal);         //是否支持tag信息
    }

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

 按钮是允许自定义的,但按钮是针对整个列表所有项目的,不能针对每个Item自定义按钮,在列表中按钮存储在一个QList中,可自行设置按钮。接下来查看Item数据结构体

///
/// 垂直时间线列表项数据结构
///
typedef struct LQTIMELINELIST_ITEM_{
    uint64_t                     uTimeLineIndex;         //索引ID
    std::u16string               sViewDataIndex;         //视图数据ID
    std::u16string               sTimeLineValue;         //时间
    std::u16string               sTimeLineTitle;         //时间线标题
    std::u16string               sTimeLineBodys;         //时间线正文
    uint64_t                     uItemsGroupIds = 0;     //分组ID
    QList<std::u16string>        vItemImgObject;         //图像附件路径列表
    QList<std::u16string>        vItemVideoObjs;         //视频附件路径列表
    std::u16string               sItemAudioPath;         //音频附件路径列表
    std::u16string               sItemsViewUrls;         //更多信息URL
    std::u16string               sItemsDescInfo;         //描述信息,不能太长
    QVariant                     pItemsAppDatas;         //自定义数据

    QList<uint32_t>              vOptsTagsCount;         //选项标识数量,根据按钮索引数量提供,不需要的则为0
    QList<bool>                  vOptSelfChecks;         //选项是否选中,根据按钮索引数量提供,按钮属性不支持的则不会应用此属性
}LQTIMELINELIST_ITEM,*PLQTIMELINELIST_ITEM;

/// 时间线分组数据结构体
typedef struct QTIMELINELIST_GROUP_{
    uint64_t                     uItemsGroupIds;         //分组ID
    std::u16string               sItemGroupName;         //分组名称
    bool operator == (const QTIMELINELIST_GROUP_& rhs) // 操作运算符重载
    {
        return (uItemsGroupIds == rhs.uItemsGroupIds)
               && (sItemGroupName == rhs.sItemGroupName);          //是否显示选项按钮
    }

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

/// 时间线列表项数据结构
typedef struct QTIMELINELIST_VIEWDATA_
{
    QTIMELINELIST_GROUP           tTimeLineGroup;     //分组
    QList<LQTIMELINELIST_ITEM>    vSubsListItems;     //组内数据

    ~QTIMELINELIST_VIEWDATA_()
    {
        vSubsListItems.clear();
    }
}QTIMELINELIST_VIEWDATA,*PQTIMELINELIST_VIEWDATA;

既然是使用QListView,那么风格委托是重中之重,风格委托代码定义如下

class LNCF_QTSOCIALLIBS_API Lncf_TimelineListd: public Lncf_QListDelegate
{
    Q_OBJECT
    mutable QTextEdit     pBodyTxtSelect;
public:
    Lncf_TimelineListd(QObject *parent =nullptr);
    ~Lncf_TimelineListd();
protected:
    /// 初始化列表委托
    /// \brief InitTimeLineListd
    ///
    void InitTimeLineListd();
private:
    /// 列表项风格委托样式数据结构变量
    /// \brief tDelegateStyle
    ///
    QTIMELINELIST_STYLE   tDelegateStyle;

    std::u16string        sImageCoverObj;        //默认图片封面路径
    std::u16string        sVideoCoverObj;        //默认视频封面路径
    std::u16string        sAudioCoverObj;        //默认音频封面路径
    std::u16string        sTagFromTxtVal;        //描述信息前缀信息
    std::u16string        sHelpDescTexts;        //帮助URL描述文字

    QImage                pImageCoverObj;        //默认图片封面对象
    QImage                pVideoCoverObj;        //默认视频封面对象
    QImage                pAudioCoverObj;        //默认音频封面对象

    uint                  uItemAlignType = 0;    //0居中对齐,1左对齐,2右对齐

    bool                  bIsShowEditBtn = true;  //是否显示编辑按钮
    bool                  bShowTitleText = true;  //是否显示标题文本
    bool                  bShowGroupText = true;  //是否显示分组文本
    bool                  bShowBodyTitle = true;  //是否显示正文标题
    bool                  bIsShowTagText = true;  //是否显示标识文本
    bool                  bContentSelect = true;  //是否允许内容选中
    bool                  bIsShowHelpUrl = true;  //是否显示帮助URL
    bool                  bIsShowOptsBtn = true;  //是否显示选项按钮

    bool                  bDrawsHtmlText = false; //是否绘制html文本
    QFont                 fTimeFontsObjs;         //时间字体
    QFont                 fBodyTitleFont;         //正文标题文本字体
    QFont                 fTextFontsObjs;         //文字字体
    QFont                 fTitlesFontObj;         //标题字体
    QFont                 fGroupsFontObj;         //分组字体
    QFont                 fTagTxtFontObj;         //标识文本字体
    QFont                 fDescFontsObjs;         //描述信息文本字体
    QFont                 fViewsUrlsFont;         //url字体

    uint                  uTitleMaxiLens = 64;   //标题最大长度
    uint                  uContentMaxLen = 256;   //内容最大长度

    std::u16string        sEditButtonTip;         //编辑按钮提示信息
    std::u16string        sTitleTxtValue;         //标题文本
    std::u16string        sEditButtonIco;         //编辑按钮图标路径
    std::u16string        sMediaCoverTip;         //媒体封面提示信息
    std::u16string        sHelpUrlTipInf;         //帮助链接提示信息
    std::u16string        sGroupTipsText;         //分组提示信息
    std::u16string        sTitleTipsText;         //标题提示信息

    QImage                pEditButtonIco;         //编辑按钮图标对象
    int                   nRowCountValue = 0;     //数据总行数
    QListView            *pListViewsObjs = nullptr;
    QList<QTIMELINELIST_OPTBN> vItemOptBtnInf;        //选项按钮信息,例如按照顺序分别是:1点赞,2反对,3喜欢,4收藏,5评论,6分享,7更多,需要自己配置按钮信息

private:
    mutable double        dTimeRectWidth = 0;     //时间内容区域宽度
    mutable double        dOptsRectWidth = 0;     //选项按钮区域宽度
    mutable double        dLineOffsetVal = 0;     //垂直线条左侧偏移量
private:
    /// 重写系统绘制
    void paint(QPainter *painter, const QStyleOptionViewItem &option,const QModelIndex &index) const Q_DECL_OVERRIDE;

    /// 绘制标题
    /// \brief DrawsTitleItems
    /// \param painter
    /// \param option
    /// \param index
    /// \param sTitle
    ///
    void DrawsTitleItems(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index) const;

    /// 绘制分组项
    /// \brief DrawGroupsItems
    /// \param painter
    /// \param option
    /// \param index
    /// \param tGroup
    ///
    void DrawGroupsItems(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index,QTIMELINELIST_GROUP tGroup) const;

    /// 绘制左对齐项
    /// \brief DrawLeftItemInf
    /// \param painter
    /// \param option
    /// \param index
    /// \param tData
    ///
    void DrawLeftItemInf(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index,const LQTIMELINELIST_ITEM &tData) const;

    /// 绘制右对齐项
    /// \brief DrawLeftItemInf
    /// \param painter
    /// \param option
    /// \param index
    /// \param tData
    ///
    void DrawRighItemInf(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index,const LQTIMELINELIST_ITEM &tData) const;

    /// 绘制选项按钮
    /// \brief DrawLeftOptBtns
    /// \param painter
    /// \param option
    /// \param index
    /// \param tData
    ///
    void DrawOptsButtons(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index,const LQTIMELINELIST_ITEM &tData) const;

    /// 绘制居中对齐项
    /// \brief DrawCenterItems
    /// \param painter
    /// \param option
    /// \param index
    /// \param tData
    ///
    void DrawCenterItems(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index,const LQTIMELINELIST_ITEM &tData) const;

    /// 绘制居中对齐左侧项
    /// \brief DrawCenterLefts
    /// \param painter
    /// \param option
    /// \param index
    /// \param tData
    ///
    void DrawCenterLefts(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index,const LQTIMELINELIST_ITEM &tData) const;

    /// 绘制居中对齐右侧项
    /// \brief DrawCenterRight
    /// \param painter
    /// \param option
    /// \param index
    /// \param tData
    ///
    void DrawCenterRight(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index,const LQTIMELINELIST_ITEM &tData) const;

    /// 绘制正文内容
    /// \brief DrawBodyContent
    /// \param painter
    /// \param option
    /// \param index
    /// \param tData
    ///
    void DrawBodyContent(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index,const LQTIMELINELIST_ITEM &tData) const;

    /// 绘制时间
    /// \brief DrawTimeContent
    /// \param painter
    /// \param option
    /// \param index
    /// \param tData
    ///
    void DrawTimeContent(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index,const std::u16string sTime) const;

    /// 绘制中间节点
    /// \brief DrawCentersNode
    /// \param painter
    /// \param option
    /// \param index
    /// \param tData
    ///
    void DrawCentersNode(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index) const;

    /// 绘制居中对齐选项按钮
    /// \brief DrawCenterOptBn
    /// \param painter
    /// \param option
    /// \param index
    /// \param tData
    /// \param bRight:正文内容是否靠右对齐,根据index行数判断,在不显示标题的情况下,偶数靠左,奇数靠右,否则奇数靠左,
    /// 偶数靠右,或者按照行数序列建立索引,Title与group不参与其中,丛第一条数据开始判断TIMELINELIST_TYPES类型,
    ///
    void DrawCenterOptBn(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index,const LQTIMELINELIST_ITEM &tData) const;

    /// 绘制项目封面
    /// \brief DrawItemsCovers
    /// \param painter
    /// \param option
    /// \param index
    /// \param tData
    ///
    void DrawItemsCovers(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index,const LQTIMELINELIST_ITEM &tData) const;

    /// 绘制项目描述信息
    /// \brief DrawItemDescInf
    /// \param painter
    /// \param option
    /// \param index
    /// \param tData
    ///
    void DrawItemDescInf(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index,const LQTIMELINELIST_ITEM &tData,const double vRadiusArr[4],
                         const bool bLeftTopRadius,const bool bLeftBtmRadius,const bool bRighBtmRadius,bool bRighTopRadius,uint uMediaCount) const;

private:
    /// 获取元素矩形区域
    /// \brief GetElementRect
    /// \param option
    /// \param index
    /// \param nType: 根据项目类型计算高度,内容类型,0数据,1分组,2标题
    /// \param nIndex 0:正文全局区域,1选项按钮全局区域,2编辑按钮区域,3正文标题,4正文内容,5正文媒体封面全局区域,6正文描述区域,7时间
    /// \param tData: nType为0时被赋值
    /// \param sText: nType不等于0时被赋值
    /// \return
    ///
    QRectF GetElementRect(const QStyleOptionViewItem &option,const QModelIndex &index,const int nType,const int nIndex,const LQTIMELINELIST_ITEM &tData,const std::u16string& sText) const;

    /// 获取标题矩形区域
    /// \brief GetTitlesRects
    /// \param option
    /// \param index
    /// \param sTitle
    /// \return
    ///
    QRectF GetTitlesRects(const QStyleOptionViewItem &option,const QModelIndex &index,const std::u16string& sTitle) const;

    /// 获取分组矩形区域
    /// \brief GetGroupsRects
    /// \param option
    /// \param index
    /// \param sGroup
    /// \return
    ///
    QRectF GetGroupsRects(const QStyleOptionViewItem &option,const QModelIndex &index,const std::u16string& sGroup) const;

    /// 获取中轴线左侧内容区域
    /// \brief GetCentersLeft
    /// \param option
    /// \param index
    /// \param nIndex 0:正文全局区域,1选项按钮全局区域,2编辑按钮区域,3正文标题,4正文内容,5正文媒体封面全局区域,6正文描述区域,7时间
    /// \return
    ///
    QRectF GetCentersLeft(const QStyleOptionViewItem &option,const QModelIndex &index,const int nIndex,const LQTIMELINELIST_ITEM &tData) const;

    /// 获取中轴右侧内容区域
    /// \brief GetCenterRight
    /// \param option
    /// \param index
    /// \param nIndex 0:正文全局区域,1选项按钮全局区域,2编辑按钮区域,3正文标题,4正文内容,5正文媒体封面全局区域,6正文描述区域,7时间
    /// \return
    ///
    QRectF GetCenterRight(const QStyleOptionViewItem &option,const QModelIndex &index,const int nIndex,const LQTIMELINELIST_ITEM &tData) const;

    /// 获取左对齐内容区域
    /// \brief GetLeftMsgRect
    /// \param option
    /// \param index
     \param nIndex 0:正文全局区域,1选项按钮全局区域,2编辑按钮区域,3正文标题,4正文内容,5正文媒体封面全局区域,6正文描述区域,7时间
    /// \return
    ///
    QRectF GetLeftMsgRect(const QStyleOptionViewItem &option,const QModelIndex &index,const int nIndex,const LQTIMELINELIST_ITEM &tData) const;

    /// 获取右对齐内容区域
    /// \brief GetRithMsgRect
    /// \param option
    /// \param index
    /// \param nIndex 0:正文全局区域,1选项按钮全局区域,2编辑按钮区域,3正文标题,4正文内容,5正文媒体封面全局区域,6正文描述区域,7时间
    /// \return
    ///
    QRectF GetRithMsgRect(const QStyleOptionViewItem &option,const QModelIndex &index,const int nIndex,const LQTIMELINELIST_ITEM &tData) const;

    /// 获取选项按钮单个索引矩形区域
    /// \brief GetOptionsRect
    /// \param rcFrame
    /// \param nIndex
    /// \param uAlign  :对齐方式,1从左向右,2从右向左
    /// \return
    ///
    QRectF GetOptionsRect(const QRectF rcFrame,const int nIndex,uint uAlign) const;

    /// 获取选项区域最小宽度
    /// \brief GetOptMinWidth
    /// \return
    ///
    double GetOptMinWidth() const;

    /// 获取垂直竖线
    /// \brief GetVlineOffset
    /// \return
    ///
    double GetVlineOffset(const QStyleOptionViewItem &option) const;

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

    /// 获取选项按钮区域宽度
    /// \brief GetOptsRectWid
    /// \return
    ///
    double GetOptsRectWid() const;

    /// 计算高度
    /// 注意:高度的计算在有媒体的时候文本区域最低高度不低于媒体封面最小高度
    /// \brief CalcItemHeight
    /// \param option
    /// \param index
    /// \param uType :内容类型,0数据,1分组,2标题
    /// \return
    ///
    int CalcItemHeight(const QStyleOptionViewItem &option, const QModelIndex &index,const uint uType,const uint uAlign) const;

您根据上面的代码您可以自定义实现辅助函数从而实现一个垂直时间线列表,自己在完成属性接口与信号连接即可使用。详细代码暂不透露,计划做成商业控件库,后期也可能开源,敬请期待。

有关技术分享和控件以及商业合作交流请加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、付费专栏及课程。

余额充值