`
qimo601
  • 浏览: 3449131 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

更新QTableView中的进度条状态

    博客分类:
  • Qt
阅读更多

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

 

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

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

 

 

解决方法:今天才发现,实际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);
    }
    
}

 

实现结果:

 

 


参考文章:

 

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

 

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

  • 大小: 112.4 KB
  • 大小: 109.7 KB
分享到:
评论
2 楼 xhmbs 2017-03-06  
简直太厉害了
1 楼 tadpole_java 2015-02-11  
看帖不回不好,

相关推荐

    qtableview 自定义委托 checkbox,进度条、时间等控件

    此外,可能还需要监听模型数据的改变,以便及时更新进度条的状态。 3. **时间(Time)**:若要在表格中显示时间信息,可以使用QTimeEdit控件。自定义委托需覆盖`createEditor()`方法,以在单元格内创建时间编辑器。...

    QTableView插入QCheckBox复选框

    同时,我们也需要确保用户在表格中手动更改复选框时,其他复选框的状态也会相应更新。 6. **展示QTableView** 最后,将自定义的数据模型设置到QTableView中,并设置自定义的表头视图。这样,我们就创建了一个带有...

    Qt之模型/视图(实时更新数据)

    这里添加了进度条委托,意味着在表格中,每个文件的进度信息会以进度条的形式呈现。 4. **添加、更新、删除、清空操作**:模型需要提供这些基本操作接口,当视图接收到用户的这些操作请求时,会调用相应的模型方法...

    qt5 音乐播放器

    这款音乐播放器的核心功能包括播放、暂停、循环播放以及进度条的设置和显示,这些都是多媒体应用中的基本要素。 首先,Qt5音乐播放器的播放功能是通过Qt的多媒体模块(QMediaPlayer)实现的。QMediaPlayer类提供了...

    用qt利用tablewidget等控件

    3. 复选框:在`QTableWidgetItem`中,可以启用复选框功能,通过`setCheckState()`设置状态,`checkState()`获取状态。 三、其他控件与QTableWidget的配合 1. QHeaderView:`QTableWidget`的头部分为水平(列)和...

    qt音乐播放器代码

    7. **状态管理**:QMediaPlayer提供了多种状态,如Playing、Paused、Stopped等,开发者可以通过查询这些状态来决定如何响应用户的操作,例如在播放状态下,点击播放按钮可以暂停音乐,而在暂停状态下则可以继续播放...

    基于QT的多种自定义美化的界面控件

    在表格方面,QT的`QTableView`或`QTableWidget`是常用的控件。为了美化,你可以自定义单元格的样式、字体、背景色,甚至可以使用`QStyledItemDelegate`来定制单元格的行为和显示。例如,可以创建一个自定义委托,...

    python制作的学生信息管理系统(2)

    4. **读取和显示数据**:使用QTextStream从文本文件读取学生信息,填充到数据模型中,然后更新QTableView显示。 5. **保存数据**:当用户添加、删除或修改学生信息后,将数据模型的内容写回文本文件。 6. **错误...

    QT写的文件搜索器(Designer窗体设计结合代码)

    此外,为了提高用户体验,还可以添加进度条(QProgressBar)显示搜索进度,或者状态栏(QStatusBar)显示搜索状态和提示信息。 总的来说,这个"QT写的文件搜索器"项目展示了如何利用Qt Designer创建用户界面,以及...

    QT的增删改查

    1. 创建QMediaPlayer对象,设置其错误和状态改变的信号槽,以便处理播放过程中的异常和状态变化。 2. 创建QMediaPlaylist对象,并将其设置为QMediaPlayer的播放列表。 3. 加入音乐文件,可以使用addMedia()方法,...

    QT简单音乐播放器(访网易云)

    这需要将`QMediaPlayer`的信号与UI元素的槽连接起来,如`metadataChanged()`信号可以更新歌曲信息,`positionChanged()`更新进度条。 6. **音频流处理**:`QMediaPlayer`可以处理多种音频格式,但若需要更高级的...

    经典的音乐播放器软件代码

    通过与`QMediaPlayer`的连接,可以实时更新进度条的状态,同时响应用户的拖动操作来改变播放位置。 4. **音量控制(QDial或QSlider)**:使用`QDial`或`QSlider`来调整音量。通过设置`QMediaPlayer`的音量属性,...

Global site tag (gtag.js) - Google Analytics