一、直接在表格里添加,利用setCellWidget或setIndexWidget
QTableWidget::setCellWidget(int row, int column, QWidget *widget)
QAbstractItemView::setIndexWidget(const QModelIndex &index, QWidget *widget)
以下代码是在tableWidget里加入进度条,一个进度条对应于一个线程里的工作;
for(int i=0;i<num_1;i++)
{
bar[i]=new QProgressBar(this);
bar[i]->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
bar[i]->setFixedSize(300,30);
bar[i]->setMaximum(100);
bar[i]->setMinimum(0);
bar[i]->setFormat(QString("当前进度为:%1%").arg(i));
bar[i]->setValue(5);
obj[i] = new objthread(bar[i]);//把相应的progressbar传到线程obj里,这样在obj里可以传出来设置对应的bar的value
thread[i]= new QThread();
obj[i]->moveToThread(thread[i]);
thread[i]->start();
connect(thread[i],SIGNAL(finished()),thread[i],SLOT(deleteLater()));
connect(thread[i],SIGNAL(finished()),obj[i],SLOT(deleteLater()));
//obj里传出来对应的bar来设置其value
connect(obj[i],SIGNAL(setprogressvalue(QProgressBar*,int,QString)),this,SLOT(setprogressvalue(QProgressBar*,int,QString)));
//tablewidget,下面是把qprocessbar放在qtablewidget里
ui->tableWidget->insertRow(0);
ui->tableWidget->setCellWidget(0,0,bar[i]);
}
//以下是槽
void Widget::setprogressvalue(QProgressBar *mbar, int value, QString filename)
{
mbar->setValue(value);
double dProgress = (mbar->value() - mbar->minimum()) * 100.0
/ (mbar->maximum() - mbar->minimum());
mbar->setFormat(QString("%1当前进度为:%2%").arg(filename).arg(QString::number(dProgress, 'f', 1)));
}
二、通过委托
需要重写以下两个函数,并且需要自定义model,使model里的某一列的值对应bar的value;(这样就能通过改变model值使bar自动步进了)
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index);
void pbar_delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if(index.data().type() == QVariant::Int)
{
int radio=5;
int top = option.rect.top() + radio;
int left = option.rect.left() + radio;
int width = option.rect.width() - 2 * radio;
int height = option.rect.height() - 2 * radio;
QStyleOptionProgressBar bar;
bar.rect.setRect(left,top,width,height);//设置其在表格中的位置
bar.state = QStyle::State_Enabled;
//设置对应model列的值,需要自定义model
bar.progress = index.data(Qt::EditRole).toInt();
bar.maximum =100;
bar.minimum = 0;
bar.textVisible = true;
bar.text = QString("aaaaaaaa:%1").arg(bar.progress);
bar.textAlignment = Qt::AlignCenter;
QProgressBar pbar;
QApplication::style()->drawControl(QStyle::CE_ProgressBar,&bar,painter,&pbar);
}
else QItemDelegate::paint(painter,option,index);
}
bool pbar_delegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
if(event->type() == QEvent::MouseButtonDblClick)//禁止双击编辑
return true;
return QItemDelegate::editorEvent(event,model,option,index);
}
三、两者区别
1、第一种方法代码上简单点,容易理解;缺点是不能设置bar在表格里的位置,不能居中。
如果设置bar高度小于表格高度,则bar会贴着表格上沿:如下图
当bar高度大于等于表格高度时,会填满表格,看着还好!
2、委托的方法代码较多,好处也不少;可以设置其在表格里的位置(比如居中);并且也能用样式文件来改变其样式(原来以为paint出来的控件不能用样式来着汗-_-||)。并且也可以通过改变model里对应列的值来使bar步进(当然这需要自定义model)。
bar.rect.setRect(left,top,width,height);//设置其在表格中的位置
四、第三种,万能Qwidget,自定义QWidget
在QWidget里加入进度条(可以添加任意多个控件)并进行布局,利用setCellWidget或setIndexWidget进行添加。效果等同于委托。
可以对进度条修饰。