Qt implementation time range selection

We wrote an article before Using Qt ScrollBar to realize scrolling screen time selector I also wrote an article QComboBox custom settings - the drop-down list is customized as a table Today, we will use the previous two articles to implement a time range selection control.

First, let's look at the effect.

After seeing the effect, we decompose the above control:

  1. The outermost layer is a QComboBox control, which is customized by us
  2. In the drop-down box is a QWidget, and two identical datetime s are used to realize the start of time selection
  3. Each datetime has a QCalendarWidget (date) control and a time selection control implemented by us

With the above decomposition, we have almost understood the structure of the control.

As mentioned above, how to customize QComboBox and how to implement a datetime component have been mentioned in the previous chapters, which will not be repeated here. If necessary, please click the link yourself.

Let's simply say that we need to customize the QComboBox today. As follows, declare a class and let it inherit from QComboBox. In addition to using the constructor of the base class, we provide a common constructor.

class DateTimeEdit : public QComboBox
{
    Q_OBJECT
public:
	using QComboBox::QComboBox;
	DateTimeEdit(QWidget* parent = Q_NULLPTR);
    ~DateTimeEdit();

private:
	void initPage();
};

Because this class inherits from QComboBox, other member functions can directly use QComboBox instead of providing interfaces.

The implementation of the private function initPage is as follows:

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();
	});
}

First, create a new QTableWidget, and set the single row and single column of the table. The header and scroll bar are not visible. And set the custom model of this class as the table model. The view is set to table. The code is as follows:

this->setModel(table->model());
this->setView(table);

The next two signal slots are mainly used to set the time range set from the drop-down box. Another important reason is that the original QComboBox drop-down box will automatically hide the pop after we select an item, but after we customize it, the derived DateTimeEdit class can't get this signal, so we need to call its function to hide the drop-down box manually.

Next, let's look at the second one, implement the QWidget, and set it as a cellWidget of QTableWidget in the drop-down box when customizing the QComboBox.

Customize a class and inherit 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;
};

The function of the following function is also relatively simple. It sends signals to the DateTimeEdit mentioned above through two signal slots. And the previous time setting is delayed by one week when building.

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"));
}

The use of this control is very simple. Easily pull a QComboBox and promote it to the DateTimeEdit class of our custom control above.

Then set it.

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));

Test code.

Keywords: C++ Qt

Added by NoDoze on Mon, 22 Nov 2021 03:11:54 +0200