以前我们写过一篇利用Qt ScrollBar实现滚动屏时间选择器的文章,也写过一篇QComboBox自定义设置 - 下拉列表自定义为表格的文章,今天我们就利用前面已经完成的这两篇文章实现一个时间范围选择的控件。
首先我们看下效果。
看完了效果之后,我们对上面的这个控件进行分解:
- 最外层是一个
QComboBox
控件,只是该控件是我们自定义之后的 - 下拉框中是一个
QWidget
,并且用了两个相同的datetime来实现时间选择的起始 - 每个datetime中均有一个
QCalendarWidget
(日期)控件和一个我们自实现的时间选择控件
有了上面的分解,我们对控件的结构其实就已经差不多明了了。
上面所说的,怎样自定义QComboBox
和怎样实现一个datetime
的组件已经在前面的章节中提过了,这里不再赘述,如有需要,请自行点击链接。
我们简单的说下今天需要自定的QComboBox
,如下,申明一个类,并让其继承于QComboBox。提供的构造函数除了使用基类的构造之外,我们再提供给一个普通的构造。
class DateTimeEdit : public QComboBox
{
Q_OBJECT
public:
using QComboBox::QComboBox;
DateTimeEdit(QWidget* parent = Q_NULLPTR);
~DateTimeEdit();
private:
void initPage();
};
因为这个类是继承自QComboBox
的,所以其他的成员函数直接使用QComboBox
的便可,不在提供接口。
私有函数initPage的实现如下:
void DateTimeEdit::initPage()
{
auto table = new QTableWidget;
table->setMinimumHeight(520);
table->verticalHeader()->setVisible(false);
table->horizontalHeader()->setVisible(false);
table->setColumnCount(1);
table->setRowCount(1);
auto cell = new DateTimeRangeWidget;
table->setCellWidget(0, 0, cell);
this->setModel(table->model());
this->setView(table);
connect(cell, &DateTimeRangeWidget::signal_dateTime, this, [this](const QString& text) {
this->setEditText(text);
this->hidePopup();
});
connect(cell, &DateTimeRangeWidget::signal_cancel, this, [=] {
hidePopup();
});
}
首先new
一个QTableWidget
,并且设置该表格单行单列,表头和滚动条不可见。并且设置自定义该类的模型为表格的模型。视图设置为table。代码如下所示:
this->setModel(table->model());
this->setView(table);
接下来对的两个信号槽的目的主要是为了设置从下拉框中设置上来的时间范围。并且还有一个很重的原因是:原本的QComboBox
下拉框在我们进行选择item后,会自动进行popup
的隐藏,但当我们进行了自定义之后,派生的DateTimeEdit
类是拿不到这个信号的,因此需要我们手动调用其隐藏下拉框的函数。
接下来我们看下第二个,实现这个QWidget
,并且在自定义QComboBox
的时候将其当作是QTableWidget的一个cellWidget设置到下拉框中。
自定义一个类,继承QWidget。
class DateTimeRangeWidget : public QWidget
{
Q_OBJECT
public:
explicit DateTimeRangeWidget(QWidget *parent = 0);
~DateTimeRangeWidget();
signals:
void signal_dateTime(const QString& strDate);
void signal_cancel();
private:
void initPage();
private:
Ui::DateTimeRangeWidget *ui;
};
下面函数的功能也是比较简单的,通过两个信号槽向上面我们说的DateTimeEdit发送信号。并且在构建的时候将前一个时间设置延后一周。
void DateTimeRangeWidget::initPage()
{
connect(ui->btnYes, &QPushButton::clicked, this, [this] {
QString start = ui->wdgStart->datetime();
QString end = ui->wdgEnd->datetime();
emit signal_dateTime(QString("%1 - %2").arg(start).arg(end));
});
connect(ui->btnCancel, &QPushButton::clicked, this, [this] {
emit signal_cancel();
});
QDateTime date = QDateTime::currentDateTime();
ui->wdgStart->setDateTime(date.addDays(-7).toString("yyyy-MM-dd hh:mm:ss"));
}
该控件的使用是非常简单的,顺手拉一个QComboBox
,并将其提升为我们上面自定的控件 DateTimeEdit
类。
然后设置其即可。
QDateTime date = QDateTime::currentDateTime();
QString start = date.addDays(-7).toString("yyyy-MM-dd hh:mm:ss");
QString end = date.toString("yyyy-MM-dd hh:mm:ss");
ui->cmbTime->setEditText(QString("%1 - %2").arg(start).arg(end));
测试代码。