博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Qt之模型/视图(自定义进度条)
阅读量:6088 次
发布时间:2019-06-20

本文共 3505 字,大约阅读时间需要 11 分钟。

简述

在之前的章节中分享过关于QHeaderView表头排序、添加复选框等内容,相信大家模型/视图、自定义风格有了一定的了解,下面我们来分享一个更常用的内容-自定义进度条。

实现方式:

  1. 从QAbstractTableModel中设置对应的进度数据,因为我们需要显示进度条,而不是直接显示进度文本,所以原始的数据不需要直接显示在界面上,所以不需要使用Qt::DisplayRole,可以使用Qt::UserRole来代替。

  2. 委托QStyledItemDelegate中根据进度索引所对应的数据来获取进度,然后为QStyleOptionProgressBar设置进度值、显示文本等信息。

  3. 设置样式,这里需要QStyle在绘制的时候设置drawControl的最后一个参数,是一个QWidget *,这里我们使用QProgressBar即可。

效果

这里写图片描述

数据结构

下面定义了文件名、大小、状态、进度所对应的列,以及一个保存数据的结构体。

#define FILE_DOWNLOAD_FILE_NAME_COLUMN           0#define FILE_DOWNLOAD_SIZE_COLUMN                1#define FILE_DOWNLOAD_STATUS_COLUMN              2#define FILE_DOWNLOAD_PROGRESS_COLUMN            3// 下载记录struct FileDownloadRecord{    QString strFileName;         //文件名称    qint64 nSize;                //大小    int nStatus;                 //状态    int nProgress;               //进度};

QStyledItemDelegate

这里只有绘制部分的代码,model对应的代码这里不再列出,可以参考其它对应的文章。

源码

void ProgressBarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const{    QStyleOptionViewItem viewOption(option);    initStyleOption(&viewOption, index);    if (option.state.testFlag(QStyle::State_HasFocus))        viewOption.state = viewOption.state ^ QStyle::State_HasFocus;    QStyledItemDelegate::paint(painter, viewOption, index);    if (index.column() == FILE_DOWNLOAD_PROGRESS_COLUMN)    {        int nProgress = index.model()->data(index, Qt::UserRole).toInt();        int nLeft = 8;        int nTop = 8;        int nWidth = option.rect.width() - 2 * nLeft;        int nHeight = option.rect.height() - 2 * nTop;        // 设置进度条的风格        QStyleOptionProgressBar progressBarOption;        progressBarOption.initFrom(option.widget);        // 设置进度条显示的区域        progressBarOption.rect = QRect(option.rect.left() + nLeft, option.rect.top() + nTop,  nWidth, nHeight);        // 设置最小值        progressBarOption.minimum = 0;        // 设置最大值        progressBarOption.maximum = 100;        // 设置对齐方式        progressBarOption.textAlignment = Qt::AlignCenter;        // 设置进度        progressBarOption.progress = nProgress;        // 设置文本(百分比)        progressBarOption.text = QString("%1%").arg(nProgress);        // 设置文本可见        progressBarOption.textVisible = true;        QProgressBar progressBar;        //绘制进度条        QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption, painter, &progressBar);    }}

QThread

为了模拟真实性,所以起了一个线程,每隔1秒刷新一次。

FileDownloadThread::FileDownloadThread(QObject *parent)    : QThread(parent){    qRegisterMetaType
>("QList
");}FileDownloadThread::~FileDownloadThread(){ requestInterruption(); wait();}void FileDownloadThread::run(){ while (!isInterruptionRequested()) { QTime time; time= QTime::currentTime(); qsrand(time.msec()+time.second()*1000); QList
list; for (int i = 0; i < 5; ++i) { FileDownloadRecord record; record.strFileName = QString("/root/user/file%1.log").arg(i + 1); record.nSize = 1024 / ((i + 2) *(i + 2)) ; record.nStatus = i; record.nProgress = qrand() % 100 + 1; list.append(record); } emit transfer(list); msleep(1000); }}

样式

QProgressBar{        border: none;        text-align: center;        background: rgb(210, 225, 240);}QProgressBar::chunk {        background: rgb(0, 160, 230);}

衍伸

这里为了美观,我设置进度条距离左、上、右、下的距离均为8px,而且单元格里面只显示了一个进度条。

这里只需要控制好单元格绘制区域位置rect即可,你可以在里面添加任意自定义的控件,而且可以添加任意多个,随意排列组合。

你可能感兴趣的文章
tomcat多应用之间如何共享jar
查看>>
Flex前后台交互,service层调用后台服务的简单封装
查看>>
MySQL入门12-数据类型
查看>>
Windows Azure 保留已存在的虚拟网络外网IP(云服务)
查看>>
修改字符集
查看>>
HackTheGame 攻略 - 第四关
查看>>
js删除数组元素
查看>>
带空格文件名的处理(find xargs grep ..etc)
查看>>
华为Access、Hybrid和Trunk的区别和设置
查看>>
centos使用docker下安装mysql并配置、nginx
查看>>
关于HTML5的理解
查看>>
需要学的东西
查看>>
Internet Message Access Protocol --- IMAP协议
查看>>
Linux 获取文件夹下的所有文件
查看>>
对 Sea.js 进行配置(一) seajs.config
查看>>
第六周
查看>>
解释一下 P/NP/NP-Complete/NP-Hard 等问题
查看>>
javafx for android or ios ?
查看>>
微软职位内部推荐-Senior Software Engineer II-Sharepoint
查看>>
sql 字符串操作
查看>>