DTK进度条控件DWaterProgress
简介
DTK提供了好几种漂亮的进度条控件,我们来看下其中的DWaterProgress。
首先看下效果:
看起来很漂亮吧,特别是动态水球效果。
这个控件内置了一个定时器来动态更新水球效果,就算不调用setValue
更新进度条,水球效果也会动态变化。
如果大家有兴趣为UOS系统开发应用,建议使用DTK控件统一风格,毕竟也这么漂亮呢。
用法
使用很简单,使用setValue(newValue)
设置新值,然后调用update()
或者repaint()
。
下面看一个比较完整的用法:
MainWindow::MainWindow(QWidget* parent)
: DMainWindow(parent)
{
initUI();
initConnections();
}
void MainWindow::initUI()
{
resize(200, 200);
// 创建进度条控件
m_progress = new DWaterProgress(this);
m_progress->setFixedSize(100, 100);
m_progress->setValue(0);
m_progress->start();
auto layout = new QHBoxLayout;
layout->addWidget(m_progress);
auto frame = new DFrame(this);
frame->setLayout(layout);
// MainWindow是继承DMainWindow的主窗口,所以需要setCentralWidget
setCentralWidget(frame);
}
void MainWindow::initConnections()
{
// 创建一个更新进度条的定时器
auto timer = new QTimer(this);
timer->setInterval(500);
connect(timer, &QTimer::timeout, this, &MainWindow::onTimeout);
timer->start();
}
void MainWindow::onTimeout()
{
// 每次+1
auto value = m_progress->value() + 1;
if (value == 100)
value = 1;
// 设置新值
m_progress->setValue(value);
}
注意点
1. 需要调用start来开启UI更新
在创建控件后我们调用了start
是为了启动定时器来让控件动起来,不然界面上会一直不更新,大家可以试试不掉用start
。
那为什么是这样呢,我们看下源码:
void DWaterProgress::setValue(int value)
{
D_D(DWaterProgress);
if (d->value == value) {
return;
}
d->setValue(value);
Q_EMIT valueChanged();
}
上面是我们调用的setValue
,可以看到里面只是调用了DWaterProgressPrivate
的setValue
,我们来继续看:
void DWaterProgressPrivate::setValue(int v)
{
value = v;
progressText = QString("%1").arg(v);
}
从上面可以看到,DWaterProgressPrivate
的setValue
里只是更新了progressText
,也没有主动触发重绘。
然后在DWaterProgressPrivate::initUI
创建了定时器来触发update
:
void DWaterProgressPrivate::initUI()
{
...
value = 0;
timer = new QTimer(q);
timer->setInterval(interval);
...
q->connect(timer, &QTimer::timeout, q, [ = ] {
...
q->update();
});
}
所以,需要我们调用start
来启动定时更新。
2. 只显示百分号?
我们先看现象:
就是一开始只显示了个百分号,为啥呢,我上面代码里明明有setValue(0)
咋没起作用。
要找到原因,我们还是得看源码:
class DWaterProgressPrivate: public DTK_CORE_NAMESPACE::DObjectPrivate
{
...
QString progressText;
...
int value;
...
};
void DWaterProgressPrivate::initUI()
{
...
value = 0;
...
}
可以看到progressText
为空串
,value
在DWaterProgressPrivate::initUI
初始化为0
;
我们再看DWaterProgress
的setValue
:
void DWaterProgress::setValue(int value)
{
D_D(DWaterProgress);
if (d->value == value) {
return;
}
d->setValue(value);
Q_EMIT valueChanged();
}
注意条件if (d->value == value)
,一开始value
为0
,我们调用setValue(0)
正好就return
了,那progressText
就还是空串
,不管我们怎么触发重绘,都不会显示出0%
。
那怎么办呢,有两个办法:
- 不太介意精度的话,可以调用
setValue(1)
来初始化 - 很在意精度,可以先
setValue(-1)
,再setValue(0)
其它
DWaterProgress
还可以通过调用setTextVisible(false)
来隐藏百分比显示,这样仅用图像表示进度,在某些场合下可能是比较合适的,效果如下: