#include "timewidget.h" #include "ui_timewidget.h" #include #include #include #include #include #include "timepartwidget.h" #include "shadowwidget.h" #include "UIStyleManager.h" TimeWidget::TimeWidget(QWidget *parent , ShowType type) : QFrame(parent), ui(new Ui::TimeWidget), m_wdgTimeArea(nullptr), m_pMainWindow(parent), m_type(type) { ui->setupUi(this); Init(); } TimeWidget::TimeWidget(ShowType type) : QFrame(nullptr), ui(new Ui::TimeWidget), m_wdgTimeArea(nullptr), m_pMainWindow(nullptr), m_type(type) { ui->setupUi(this); Init(); } TimeWidget::~TimeWidget() { delete ui; } void TimeWidget::CreateTimeVector(const QVector &types) { ClearVector(m_vecTimePart); for (auto& type : types) { TimePartWidget::emSection emType = static_cast(type); if (emType >= TimePartWidget::emSection::MAX_SECTION) { continue; } TimePartWidget* pTmp = new TimePartWidget(emType, this); if (nullptr != pTmp) { pTmp->SetMaxWidth(width() / types.count()); m_vecTimePart.append(pTmp); } } } void TimeWidget::ClearVector(QVector &vec) { for (auto& pWdg : vec) { if (nullptr != pWdg) { delete pWdg; pWdg = nullptr; } } vec.clear(); } void TimeWidget::SetMainWindow(QWidget* pWidget) { if (nullptr != m_pMainWindow) { this->removeEventFilter(m_pMainWindow); } if (nullptr != pWidget) { pWidget->installEventFilter(this); } m_pMainWindow = pWidget; } /* 返回时间 */ QTime TimeWidget::getTime() { return ui->dateTimeEdit->time(); } /** * @brief 存在时间就返回hh:mm:ss.zzz格式字符串,否则返回提示信息 * @return */ QString TimeWidget::getTimeStr() { QString ret(ui->lbl_tip->text()); if (!ui->dateTimeEdit->isHidden()) { ret = ui->dateTimeEdit->time().toString("hh:mm:ss");//.zzz } return ret; } /** * @brief 存在返回时间,否则返回00:00:00 * @return */ QTime TimeWidget::getFormTime() const { return ui->dateTimeEdit->isHidden() ? QTime(0, 0, 0) : ui->dateTimeEdit->time(); } void TimeWidget::setTime(const QString& t) { QTime time = QTime::fromString(t, "hh:mm:ss"); ui->dateTimeEdit->setTime(time); ui->lbl_tip->hide(); ui->dateTimeEdit->show(); UpdatePopupTime(ui->dateTimeEdit->dateTime());// } void TimeWidget::setTime(const QTime& t) { ui->dateTimeEdit->setTime(t); ui->lbl_tip->hide(); ui->dateTimeEdit->show(); UpdatePopupTime(ui->dateTimeEdit->dateTime()); } void TimeWidget::clearTime() { ui->dateTimeEdit->setTime(QTime(0, 0, 0)); ui->dateTimeEdit->hide(); ui->lbl_tip->show(); } QString TimeWidget::tipText() const { return ui->lbl_tip->text(); } /* 设置时间选择区域的大小,不能超过时间编辑栏的大小,这个主要是防止时间栏太宽,影响美观 */ void TimeWidget::setTimeAreaWidth(int w) { if(w < 0) { m_width = 0; } else if(w > this->width()) { m_width = this->width(); } else { m_width = w; } } void TimeWidget::showTimeEditArea() { this->show(); ShowTimeArea(true); } /* 以弹窗的模式模态显示 */ void TimeWidget::execShow() { QEventLoop loop; connect (this, &TimeWidget::signal_close, &loop, &QEventLoop::quit); this->show(); ShowTimeArea(true); loop.exec(); deleteLater(); } /* 设置时间图标 */ void TimeWidget::setIcon(const QString& icon) { /* 设置图片适应按钮大小 */ QString ss = QString("border-image: url(%1)").arg(icon); ui->btn_tip->setStyleSheet(ss); ui->btn_tip->show(); } /* 设置图标显示 */ void TimeWidget::setIconShow(bool isShow) { if(isShow) { ui->btn_tip->show(); }else { ui->btn_tip->hide(); } } /* 设置图标大小 */ void TimeWidget::setIconSize(int w, int h) { ui->btn_tip->setMinimumSize(w, h); /* 设置为固定大小 */ ui->btn_tip->setFixedSize(w, h); // ui->btn_tip->resize(w, h); } /* 设置默认的样式 */ void TimeWidget::setDefaultStyle() { /* 判断显示类型,如果是弹窗直接显示编辑区 */ if(m_type == Dialog) { ui->btn_tip->hide(); this->resize(136,36); // ShowTimeArea(false); /* 设置编辑栏样式 */ // this->setStyleSheet(R"( // TimeWidget // { // padding-left:15px; // background: #FFFFFF; // border-radius: 4px; // border: 1px solid #E6E9F4; // } // )"); } } /* 设置编辑栏大小 */ void TimeWidget::setEditLine(int w, int h) { this->resize(w, h); } /* 设置QSS */ void TimeWidget::setQSS() { QString qssPath = EPUIStyle.getQSSPath() + "/SelectTime/timewidget.qss"; QFile file(qssPath); if(file.open(QFile::ReadOnly)) { QString styleSheet = QLatin1String(file.readAll()); setStyleSheet(styleSheet); file.close(); } // else // { // LH_WRITE_ERROR("open qss file failed: " + qssPath); // } } /** * @brief 点击提示信息 */ void TimeWidget::onBtnTipClicked() { bool isSelected = ui->btn_tip->property("selected").toBool(); if (!isSelected) { // 显示日期 ui->lbl_tip->hide(); ui->dateTimeEdit->show(); ShowTimeArea(true); } else { // 清除时间 ui->dateTimeEdit->setTime(QTime(0, 0, 0)); UpdateProperty(ui->btn_tip, "selected", false); QDateTime dt; dt.setTime(QTime(0, 0, 0)); UpdatePopupTime(dt); ShowTimeArea(false); ui->dateTimeEdit->hide(); ui->lbl_tip->show(); } } /** * @brief 这里添加了两个信号,一个是修改过的新时间,一个是旧时间 * @param obj * @param e * @return */ bool TimeWidget::eventFilter(QObject* obj, QEvent* e) { if (obj == ui->dateTimeEdit) { if (e->type() == QEvent::FocusIn && m_type == EditLine) { //qInfo() << "dateTimeEdit focusIn"; ShowTimeArea(true); UpdateProperty(ui->btn_tip, "selected", true); emit signal_formerTimer(ui->dateTimeEdit->time()); } return QWidget::eventFilter(obj, e); } else if (obj == ui->lbl_tip) { if (e->type() == QEvent::MouseButtonPress && m_type == EditLine) { //qInfo() << "mouseButtonPress"; ui->dateTimeEdit->show(); ui->lbl_tip->hide(); ShowTimeArea(true); //ui->dateTimeEdit->setFocus();// return QWidget::eventFilter(obj, e); } } else if (obj == this) { if (e->type() == QEvent::Enter) { UpdateProperty(this, "hover", true); } else if (e->type() == QEvent::Leave && ((m_wdgTimeArea.isNull() && !ui->dateTimeEdit->hasFocus()) || (m_wdgTimeArea && m_wdgTimeArea->isHidden())) ) { UpdateProperty(this, "hover", false); } } /* 判断是不是显示区外面,是的话就隐藏 */ QMouseEvent* pMouse = reinterpret_cast(e); if (nullptr != pMouse) { if (pMouse->type() == QEvent::MouseButtonPress) { //qInfo() << "focusOut"; QPoint gtl = this->mapToGlobal(rect().topLeft()); QRect rc(gtl.x(), gtl.y(), width(), height()); // 全局位置判断 if (!rc.contains(pMouse->globalPos())) { ShowTimeArea(false); ui->dateTimeEdit->clearFocus(); UpdateProperty(this, "hover", false); /* 关闭显示,发送携带时间的信号 */ emit signal_nowTime(ui->dateTimeEdit->time()); if(m_type == Dialog) { this->close(); } } } } return QWidget::eventFilter(obj, e); } /** * @brief m_wdgTimeArea跟随时间栏移动 * @param event */ void TimeWidget::moveEvent(QMoveEvent *event) { if(m_type == Dialog && m_wdgTimeArea != nullptr) { QPoint pt = this->mapTo(m_pMainWindow, QPoint(0, 0)); m_wdgTimeArea->move(QPoint(pt.x() - SHADOW_MARGIN, pt.y() + this->height())); // qDebug() << "posX:" << pt.x() << "posY:" << pt.y(); } } /** * @brief 时间列表选中事件 * @param item */ void TimeWidget::onListItemClicked(QListWidgetItem *item) { if (nullptr == item) return; TimePartWidget* pWdg = reinterpret_cast(QObject::sender()); if (nullptr == pWdg) return; QString data(item->text()); if (data.isEmpty()) return; // 过滤空白项 QDateTime oldDt(ui->dateTimeEdit->dateTime()); QTime t(ui->dateTimeEdit->time()); switch (pWdg->GetType()) { case TimePartWidget::HOUR: { t.setHMS(data.toInt(), t.minute(), t.second()); break; } case TimePartWidget::MINUTE: { t.setHMS(t.hour(), data.toInt(), t.second()); break; } case TimePartWidget::SECOND: { t.setHMS(t.hour(), t.minute(), data.toInt()); break; } default: break; } if (oldDt.time() != t) { m_bTimeFlag = true; ui->dateTimeEdit->setTime(t); } } /** * @brief QDateTimeEdit控件时间改变事件 * @param dt */ void TimeWidget::onDateTimeChanged(const QDateTime& dt) { if (dt.time() != QTime(0, 0, 0)) { UpdateProperty(ui->btn_tip, "selected", true); } // 同步到popupWidget if (!m_bTimeFlag) { UpdatePopupTime(dt); } m_bTimeFlag = false; } void TimeWidget::UpdateProperty(QObject* obj, const char *name, bool flag) { if (nullptr == obj || nullptr == name) { return; } obj->setProperty(name, flag); QWidget* pWdg = qobject_cast(obj); if (nullptr != pWdg) { this->style()->unpolish(pWdg); this->style()->polish(pWdg); } } /** * @brief 更新popup列表选中时间 * @param dt */ void TimeWidget::UpdatePopupTime(const QDateTime& dt) { // 如果时间列表还没初始化就不会设置时间了 for (int i = 0; i < m_vecTimeSections.size(); ++i) { auto type = m_vecTimeSections.at(i); TimePartWidget::emSection emType = static_cast(type); if (emType >= TimePartWidget::emSection::MAX_SECTION) { continue; } if (i < m_vecTimePart.size()) { TimePartWidget* pWdg = m_vecTimePart.at(i); if (nullptr == pWdg) continue; pWdg->SetTime(dt); } } } /** * @brief wdgTimeArea区域是创建出来的,不属于ui区域,他的父类是m_pMainWindow,因此移动的时候需要使用m_pMainWindow的坐标 * @param bShow */ void TimeWidget::ShowTimeArea(bool bShow) { if (m_wdgTimeArea.isNull()) { CreatePopupWidget(); } if (!m_wdgTimeArea.isNull()) { if (bShow) { //UpdatePopupTime(ui->dateTimeEdit->dateTime()); // 重新定位再显示 QPoint pt = this->mapTo(m_pMainWindow, QPoint(0, 0)); m_wdgTimeArea->move(QPoint(pt.x() - SHADOW_MARGIN, pt.y() + this->height())); /* 设置选择条的大小,如果没有设置m_width,就是用时间编辑栏的宽度 */ m_wdgTimeArea->resize((m_width == 0 ? width() : m_width) + 2 * SHADOW_MARGIN, TIME_AREA_HEIGHT * 6 + 2 * SHADOW_MARGIN); m_wdgTimeArea->setMaximumWidth(width() + 2 * SHADOW_MARGIN); m_wdgTimeArea->show(); UpdatePopupTime(ui->dateTimeEdit->dateTime()); } else { m_wdgTimeArea->hide(); emit signal_close(); } } } void TimeWidget::CreatePopupWidget() { // CreateTimeArea m_vecTimeSections = {TimePartWidget::HOUR, TimePartWidget::MINUTE, TimePartWidget::SECOND}; CreateTimeVector(m_vecTimeSections); m_wdgTimeArea.reset(new ShadowWidget(m_pMainWindow)); if (!m_wdgTimeArea.isNull()) { if (m_wdgTimeArea->centralWidget() != nullptr) { m_wdgTimeArea->centralWidget()->setObjectName(QLatin1String("wdg_TimeArea")); m_wdgTimeArea->centralWidget()->setStyleSheet("QWidget#wdg_TimeArea{border-radius: 2px;border: none; }"); } QHBoxLayout* hLayout = new QHBoxLayout(); hLayout->setMargin(1); hLayout->setSpacing(0); m_wdgTimeArea->setCentralLayout(hLayout); if (nullptr == m_wdgTimeArea->getLayout()) { delete hLayout; hLayout = nullptr; } m_wdgTimeArea->resize(QSize(width() + 2 * SHADOW_MARGIN, TIME_AREA_HEIGHT * 6 + 2 * SHADOW_MARGIN)); m_wdgTimeArea->setMaximumWidth(width() + 2 * SHADOW_MARGIN); m_wdgTimeArea->hide(); if (nullptr != m_wdgTimeArea->getLayout()) { foreach (auto wdg, m_vecTimePart) { m_wdgTimeArea->getLayout()->addWidget(wdg); connect(wdg, &TimePartWidget::sigItemClicked, this, &TimeWidget::onListItemClicked); } } } } /* 初始化函数 */ void TimeWidget::Init() { /* 设置QSS */ setQSS(); // InitUI ui->dateTimeEdit->hide(); ui->dateTimeEdit->installEventFilter(this); this->installEventFilter(this); ui->lbl_tip->installEventFilter(this); if (nullptr != m_pMainWindow) { m_pMainWindow->installEventFilter(this); } ui->btn_tip->setProperty("selected", false); connect(ui->btn_tip, &QPushButton::clicked, this, &TimeWidget::onBtnTipClicked); connect(ui->dateTimeEdit, &QDateTimeEdit::dateTimeChanged, this, &TimeWidget::onDateTimeChanged); setDefaultStyle(); }