900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 【QT】自定义日历弹窗

【QT】自定义日历弹窗

时间:2021-10-12 05:22:51

相关推荐

【QT】自定义日历弹窗

一、构想

自定义日历弹窗的制作主要是分为两部分,1、自定义日历,2、点击LineEdit时,将日历窗口弹出来。首先针对如何自定义日历制定思路,通过上网查询 QT自带了一个日历类QCalendarWidget,那就好办了,只需要自定义日历时继承这个日历类,再通过QPainter重新绘制。针对点击LineEdit时日历弹出来,要知道LineEdit没有点击事件的,那这样的话我们需要给它安装事件过滤器installEventFilter。

二、效果展示

图左为QT自带的日历,图右则是自定义的日历效果图

三、实现过程

日历跟lineEdit的数据交互是通过信号与槽的方式。

3.1 自定义日历的主要代码

#include "qcustomcalendartimewidget.h"#include <QLocale>#include <QPainter>#include <QTextCharFormat>#include <QProxyStyle>#include <QTableView>#include <QLayout>#include <QPushButton>#include <QLabel>#include <QDebug>#include <QMouseEvent>#include <QCalendarWidget>#include <QLabel>QCustomCalendarTimeWidget::QCustomCalendarTimeWidget(QWidget *parent): QCalendarWidget (parent){this->resize(350,250);initControl();}//鼠标事件 作用是让日历弹窗能够移动void QCustomCalendarTimeWidget::mouseMoveEvent(QMouseEvent *e){if (mousePressed & (e->buttons() & Qt::LeftButton)) {this->move(e->globalPos() - mousePoint);e->accept();}}void QCustomCalendarTimeWidget::mousePressEvent(QMouseEvent *e){if (e->button() == Qt::LeftButton) {mousePressed = true;mousePoint = e->globalPos() - this->pos();e->accept();}}void QCustomCalendarTimeWidget::mouseReleaseEvent(QMouseEvent *){mousePressed = false;}//初始化日历界面void QCustomCalendarTimeWidget::initControl(){//设置日历为中文this->setLocale(QLocale::Chinese);setNavigationBarVisible(false);setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader);setHorizontalHeaderFormat(QCalendarWidget::SingleLetterDayNames);//设置第一天为星期一QCalendarWidget::setFirstDayOfWeek(Qt::Monday);QTextCharFormat format;format.setForeground(QColor(160, 160, 160));format.setBackground(QColor(255, 255, 255));setHeaderTextFormat(format);//重绘日历上部栏initTopWidget();connect(this, &QCalendarWidget::currentPageChanged, [this](int year, int month){setDataLabelTimeText(year, month);});//日历双击响应事件connect(this, &QCalendarWidget::activated , this, &QCustomCalendarTimeWidget::setDate);}//发送时间给调用者void QCustomCalendarTimeWidget::setDate(){//通过信号将选择的时间发送出去emit signalSetCalendarTime(this->selectedDate());qDebug()<<"时间为: "<<this->selectedDate();}void QCustomCalendarTimeWidget::setDataLabelTimeText(int year, int month){m_dataLabel->setText(QStringLiteral("%1年%2月").arg(year).arg(month));}//绘制日历上部栏void QCustomCalendarTimeWidget::initTopWidget(){QWidget* topWidget = new QWidget(this);topWidget->setFixedHeight(40);topWidget->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed);QHBoxLayout* hboxLayout = new QHBoxLayout;hboxLayout->setContentsMargins(12, 0, 12, 0);hboxLayout->setSpacing(4);m_leftYearBtn = new QPushButton(this);m_leftMonthBtn = new QPushButton(this);m_rightYearBtn = new QPushButton(this);m_rightMonthBtn = new QPushButton(this);m_dataLabel= new QLabel(this);QString qss = "QLabel{font-size:18px;font-family:PingFang SC;}";m_dataLabel->setStyleSheet(qss);qss = "QPushButton{border-image:url(:/image/previousyear.png);}""QPushButton:hover{border-image: url(:/image/previousyear-hover.png);}";m_leftYearBtn->setFixedSize(16, 16);m_leftYearBtn->setStyleSheet(qss);m_leftYearBtn->setToolTip(tr("上一年"));qss = "QPushButton{border-image:url(:/image/previousmonth.png);}""QPushButton:hover{border-image: url(:/image/previous-hover.png);}";m_leftMonthBtn->setFixedSize(16, 16);m_leftMonthBtn->setStyleSheet(qss);m_leftMonthBtn->setToolTip(tr("上一月"));m_rightYearBtn->setFixedSize(16, 16);qss = "QPushButton{border-image:url(:/image/nextyear.png);}""QPushButton:hover{border-image: url(:/image/nextyear-hover.png);}";m_rightYearBtn->setStyleSheet(qss);m_rightYearBtn->setToolTip(tr("下一年"));m_rightMonthBtn->setFixedSize(16, 16);qss = "QPushButton{border-image:url(:/image/nextmonth.png);}""QPushButton:hover{border-image: url(:/image/nextmonth-hover.png);}";m_rightMonthBtn->setStyleSheet(qss);m_rightMonthBtn->setToolTip(tr("下一月"));hboxLayout->addWidget(m_leftYearBtn);hboxLayout->addWidget(m_leftMonthBtn);hboxLayout->addStretch();hboxLayout->addWidget(m_dataLabel);hboxLayout->addStretch();hboxLayout->addWidget(m_rightMonthBtn);hboxLayout->addWidget(m_rightYearBtn);topWidget->setStyleSheet("background-color: rgb(170, 170, 170");topWidget->setLayout(hboxLayout);QVBoxLayout *vBodyLayout = qobject_cast<QVBoxLayout *>(layout());vBodyLayout->insertWidget(0, topWidget);connect(m_leftYearBtn, SIGNAL(clicked()), this, SLOT(onbtnClicked()));connect(m_leftMonthBtn, SIGNAL(clicked()), this, SLOT(onbtnClicked()));connect(m_rightYearBtn, SIGNAL(clicked()), this, SLOT(onbtnClicked()));connect(m_rightMonthBtn, SIGNAL(clicked()), this, SLOT(onbtnClicked()));//显示当前的年 月setDataLabelTimeText(selectedDate().year(), selectedDate().month());}//响应上部栏四个按钮的事件void QCustomCalendarTimeWidget::onbtnClicked(){QPushButton *senderBtn = qobject_cast<QPushButton *>(sender());if (senderBtn == m_leftYearBtn){showPreviousYear();}else if (senderBtn == m_leftMonthBtn){showPreviousMonth();}else if (senderBtn == m_rightYearBtn){showNextYear();}else if (senderBtn == m_rightMonthBtn){showNextMonth();}}//绘制日历中间部分 当前点击的时间,当前时间的样式,通过QPaintervoid QCustomCalendarTimeWidget::paintCell(QPainter *painter, const QRect &rect, const QDate &date) const{if (date == selectedDate()){painter->save();//抗锯齿painter->setRenderHint(QPainter::Antialiasing);painter->setPen(Qt::NoPen);painter->setBrush(QColor(0, 145, 255));painter->drawEllipse(rect.x()+9, rect.y()+1, rect.width()-17, rect.height()-2);painter->setPen(QColor(255, 255, 255));painter->drawText(rect, Qt::AlignCenter, QString::number(date.day()));painter->restore();}else if (date < minimumDate() || date > maximumDate()){painter->save();painter->setRenderHint(QPainter::Antialiasing);painter->setPen(Qt::NoPen);painter->setBrush(QColor(249, 249, 249));painter->drawRect(rect.x(), rect.y() + 3, rect.width(), rect.height() - 6);painter->setPen(QColor(220, 220, 220));painter->drawText(rect, Qt::AlignCenter, QString::number(date.day()));painter->restore();}else if (date == QDate::currentDate()){painter->save();painter->setRenderHint(QPainter::Antialiasing);painter->setPen(QColor(0, 161, 255));painter->drawEllipse(rect.x()+9, rect.y()+1, rect.width()-17, rect.height()-2);painter->drawText(rect, Qt::AlignCenter, QString::number(date.day()));painter->restore();}else{QCalendarWidget::paintCell(painter, rect, date);}}

3.2 点击LineEdit弹出日历的主要代码

#include "mainwindow.h"#include "ui_mainwindow.h"#include <QHBoxLayout>#include <QLabel>#include <QDebug>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow){ui->setupUi(this);datePickerWidget = nullptr;initUI();}MainWindow::~MainWindow(){delete ui;}//LineEdit的左边贴一张图void MainWindow::initUI(){QLabel *iconLabel = new QLabel(this);iconLabel->setFixedSize(24,24);iconLabel->setPixmap(QPixmap(":/image/calendarico.png"));QHBoxLayout *hLayout = new QHBoxLayout();hLayout->addSpacing(12);hLayout->addWidget(iconLabel);hLayout->addSpacing(10);hLayout->addStretch();ui->lineEdit->setLayout(hLayout);ui->lineEdit->installEventFilter(this);}//时间过滤响应函数bool MainWindow::eventFilter(QObject *obj, QEvent *event){//lineEdit被点击if(qobject_cast<QLineEdit *>(obj) == ui->lineEdit &&event->type() == QEvent::MouseButtonPress) {if(!datePickerWidget)datePickerWidget = new QCustomCalendarTimeWidget(this);connect(datePickerWidget, &QCustomCalendarTimeWidget::signalSetCalendarTime, this, &MainWindow::SetDate);datePickerWidget->show();}return QObject::eventFilter(obj,event);}//接收数据的槽函数void MainWindow::SetDate(const QDate& date){ui->lineEdit->setText(date.toString("yyyy-MM-dd"));datePickerWidget->close();}

问题咨询及项目源码请加群:

QQ群

名称:IT项目交流群

群号:245022761

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。