更新QTableView中的进度条状态

时间:2024-03-15 20:28:44

前段时间,我接触了,如何在一个QTableView中加入一个控件,类似于QCheckBox QProgressBar,QLineEdit等。

 

      最近在项目中实际运用,才发现,在Qt中自定义委托,如果插入一个进度条。因为它很特殊,只能通过Paint进行绘画,而不是CreateEidtor()函数实现。

      所以我就遇到问题:前期在表格里画好一列进度条时,后期如何及时更新进度条状态。如下图Qt中的例子

更新QTableView中的进度条状态

 

 

解决方法:今天才发现,实际Qt的MVC已经实现了自动更新,是我在Model中返回到QTableView的值写成%小数。于是在Delegate中获取界面上的int值总是0,以为没成功。。。。

稍微修改一下Model中的返回值就可以了,在界面中需要修改数据地方,只要调用Model中的setData()方法,里面调用 emit DataChanged()信号,就可以通知View和Delegate一起更新了。

 

        源代码如下:

1、界面代码:QTableView、Model、Delegate初始化

 

 

/**
 *函数介绍:初始化重建作业队列
 *输入参数:无
 *返回值:  无
 */
void MainWindow::initReconJob()
{
    //数据源
    ReconJob job1;
    job1.setReconJobId(1);
    job1.setReconJobState(2);
    job1.setPatientId(1);
    job1.setPatientName("test");
    job1.setScanId(1);
    job1.setReconType(1);
    job1.setReconMode(1);
    job1.setSeriesDescrip("CT头部 ");
    job1.setSubTaskNum(15);
    job1.setFinishedSubTaskNum(0);
    job1.setRemainTime(95);
    job1.setPriority(1);
    job1.setRawDataFileName("rawData1.raw");
    ReconJob job2;
    job2.setReconJobId(2);
    job2.setReconJobState(1);
    job2.setPatientId(1);
    job2.setPatientName("test");
    job2.setScanId(1);
    job2.setReconType(1);
    job2.setReconMode(1);
    job2.setSeriesDescrip("CT头部 ");
    job2.setSubTaskNum(15);
    job2.setFinishedSubTaskNum(0);
    job2.setRemainTime(89);
    job2.setPriority(0);
    job2.setRawDataFileName("rawData2.raw");
    ReconJob job3;
    job3.setReconJobId(3);
    job3.setReconJobState(1);
    job3.setPatientId(1);
    job3.setPatientName("test");
    job3.setScanId(1);
    job3.setReconType(1);
    job3.setReconMode(1);
    job3.setSeriesDescrip("CT头部 ");
    job3.setSubTaskNum(15);
    job3.setFinishedSubTaskNum(0);
    job3.setRemainTime(89);
    job3.setPriority(0);
    job3.setRawDataFileName("rawData3.raw");

    reconQueue.append(job1);
    reconQueue.append(job2);
    reconQueue.append(job3);
    for(int i = 4; i < 12; i++)
    {
        ReconJob job4;
        job4.setReconJobId(i);
        job4.setReconJobState(1);
        job4.setPatientId(1);
        job4.setPatientName("test");
        job4.setScanId(1);
        job4.setReconType(1);
        job4.setReconMode(1);
        job4.setSeriesDescrip("CT头部 ");
        job4.setSubTaskNum(15);
        job4.setFinishedSubTaskNum(0);
        job4.setRemainTime(89);
        job4.setPriority(0);
        job4.setRawDataFileName("rawData.raw");
        reconQueue.append(job4);
    }

    //自定义表模型
    reconqueueModel = new MoReconQueue();
    reconqueueModel->setReconQueue(reconQueue);

	
    //设置视图模型
    ui.tableView->setModel(reconqueueModel);
    //设置行交替颜色
    ui.tableView->setAlternatingRowColors(true);
    //只能单选一个项
    ui.tableView->setSelectionMode(QAbstractItemView::SingleSelection);
    //选择行为为行
    ui.tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    //内容窗口自适应
    //ui.tableView->resizeColumnsToContents();
    //隐藏第8列 总任务数
    ui.tableView->setColumnHidden(8,true);	

	//自定义表委托
    delReconQueue = new DelReconQueue();
    //设置视图委托
    ui.tableView->setItemDelegate(delReconQueue);
	//自定义表模型
    delReconQueue = new DelReconQueue();
    //设置视图委托
    ui.tableView->setItemDelegate(delReconQueue);
    //是否可以编辑在模型 MoReconQueue中flags()函数设置
    //编辑事件 可以调用委托处理编辑数据
    //ui.tableView->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked);
    //最后一列全部填充View
    //ui.tableView->horizontalHeader()->setStretchLastSection(true);
}

/**
 *函数介绍:更新首个重建作业状态
 *输入参数:无
 *返回值:  无
 */
void MainWindow::updateReconJobState(QList<QVariant> job)
{
        QVariant finishedTaskNum = job.at(9);
        reconqueueModel->setData(reconqueueModel->index(0,9),finishedTaskNum);
		
	qDebug() <<"ssssssssssssssssssssssssssssssssssssssss" ;
}
 


2、Model中的部分代码:修改Model中的某一项值。

 

//编辑一个项,(项索引,项值,角色)
bool MoReconQueue::setData(const QModelIndex &index,
                           const QVariant &value, int role)
{	
	

    //模型索引要有效,必须是修改角色
    if (index.isValid()&& role == Qt::EditRole)
    {
        //行号
        int row = index.row();
        //列号
        int column = index.column();
        //获得原重建作业参数
        ReconJob job = reconQueue.at(row);
        //更新重建作业参数
        switch (column)
        {
        case 0:
            job.setReconJobId(value.toInt());
            break;
        case 1:
            job.setReconJobState(value.toInt());
            break;
        case 2:
            job.setPatientId(value.toInt());
            break;
        case 3:
            job.setPatientName(value.toString());
            break;
		case 4:
			job.setScanId(value.toInt());
        case 5:
            job.setReconType(value.toInt());
            break;
        case 6:
            job.setReconMode(value.toInt());
            break;
        case 7:
            job.setSeriesDescrip(value.toString());
            break;
        case 8:
            job.setSubTaskNum(value.toInt());
            break;
        case 9:
            job.setFinishedSubTaskNum(value.toInt());
            break;
        case 10:
            job.setRemainTime(value.toInt());
            break;
        case 11:
            job.setPriority(value.toInt());;
            break;
		case 12:
            job.setRawDataFileName(value.toString());;
            break;
        default:  return false;


        }
        //替换新的重建作业参数
        reconQueue.replace(row,job);
        //某项发生改变,发射信号( between topLeft and bottomRight inclusive)
		emit dataChanged(index, index);
        return true;
    }
    return false;
}

 从自定义的数据源中获取数据

 

/**
 *函数介绍:获取类对象的属性值
 *输入参数:无
 *返回值:  无
 */
QVariant MoReconQueue::reconQueueAt(int row, int column) const
{
    QVariant var;
	int temp;
	int temp1;
    switch (column)
    {
    case 0: var = reconQueue.at(row).getReconJobId();
        break;
    case 1: 
		var = reconQueue.at(row).getReconJobState();
		if(var == 1)
			var = "等待";
		else if (var == 2)
				var = "进行中";
        break;
    case 2: 
		var = reconQueue.at(row).getPatientId();
		//设置'病人Id'格式字符串: P:00000x;6位10进制数,不足补0;
        var = QString("P:%1").arg(var.toInt(), 6, 10, QChar('0'));
        break;
    case 3: var = reconQueue.at(row).getPatientName();
        break;
	case 4: var = reconQueue.at(row).getPatientName();
        break;
    case 5: 
		
		var = reconQueue.at(row).getReconType();
		if(var == 1)
			var = "PET重建";
		else if (var == 2)
				var = "CT重建";		
        break;
    case 6: var = reconQueue.at(row).getReconMode();
		if(var == 1)
			var = "auto";
		else if (var == 2)
				var = "offline";	
        break;
    case 7: var = reconQueue.at(row).getSeriesDescrip();
        break;
    case 8: var = reconQueue.at(row).getSubTaskNum();
        break;
    case 9: 
		temp = reconQueue.at(row).getFinishedSubTaskNum();
		temp1 = reconQueue.at(row).getSubTaskNum();
		//var = QString("%1 / %2").arg(temp,2,10,QChar('0')).arg(temp1,2,10,QChar('0'));	
		var = temp;
        break;
    case 10: 
		temp = reconQueue.at(row).getRemainTime();
		var = QString("%1:%2s").arg(temp / 60, 2, 10, QChar('0')).arg(temp % 60, 2, 10, QChar('0'));;
        break;
    case 11: var = reconQueue.at(row).getPriority();
        break;
	case 12: var = reconQueue.at(row).getRawDataFileName();
        break;
    default:  var = "无";
    }
    return var;
}

 3、自定义委托中,重载Paint()函数

 

 

//重载绘制函数
void DelReconQueue::paint(QPainter *painter, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const
{
  
	qDebug() << "`````````````````````行:"<< index.row() << "``````````````列:" << index.column() ;
    //如果是'已经完成子任务数'
    if (index.row()==0 && index.column() == 9)
    {
		
        const QAbstractItemModel *itemModel = index.model();
        //获得索引对应Model中的数据
        //double finishedSubTaskNum = itemModel->data(index, Qt::DisplayRole).toDouble();
		int finishedSubTaskNum = index.data().toInt();
        int subTaskNum = itemModel->data(itemModel->index(index.row(),8), Qt::DisplayRole).toInt();
		qDebug() << "```````````````````````````````````finishedSubTaskNum:" << finishedSubTaskNum ;
		qDebug() << "```````````````````````````````````subTaskNum:" << subTaskNum ;
        //进度条的风格选项
        QStyleOptionProgressBarV2  progressBarOption ;
        progressBarOption.rect = option.rect;
        progressBarOption.minimum = 0;
        progressBarOption.maximum = subTaskNum;
        progressBarOption.progress = finishedSubTaskNum;
        double t = finishedSubTaskNum/subTaskNum;
        progressBarOption.text = QString("%1 / %2").arg(finishedSubTaskNum,2,10,QChar('0')).arg(subTaskNum,2,10,QChar('0'));
        progressBarOption.textVisible = true;
        //绘制进度条
        QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption, painter);

    }
    else
    {
        //否则调用默认委托
        QStyledItemDelegate::paint(painter, option, index);
    }
    
}

 

实现结果:

 更新QTableView中的进度条状态

 

更新QTableView中的进度条状态


参考文章:

 

Qt自定义委托在QTableView中绘制控件、图片、文字

 

Qt实现表格内进度条展示数据

相关文章