#include "Menu.h" #include "Constant.h" #include "DatabaseManager.h" #include "Log.h" #include "ui_Menu.h" #include #include #include #include #define CONTENT_ROW 6 // 列表行 #define CONTENT_COLUMN 6 // 列表列 #define CONTENT_CELL_HEIGHT 56 // 单元格高度 Menu::Menu(QWidget* parent) : QWidget(parent) , FocusWindow() , ui(new Ui::Menu) { ui->setupUi(this); setAttribute(Qt::WA_WState_WindowOpacitySet); setWindowFlags(windowFlags() | Qt::FramelessWindowHint); setWindowOpacity(0.5); setFixedSize(800, 600); ui->stackedWidget->setCurrentIndex(0); ui->btnChannelSetting->setFocus(); QDesktopWidget* deskdop = QApplication::desktop(); QWidget::move((deskdop->width() - this->width()) / 2, (deskdop->height() - this->height()) / 2); ui->cmbYear->setView(new QListView()); ui->cmbMonth->setView(new QListView()); ui->cmbDay->setView(new QListView()); // 设置ScrollArea为栅格布局 QGridLayout* layout = new QGridLayout(ui->scrollArea); ui->scrollAreaWidgetContents->setLayout(layout); db = DatabaseManager::getInstace(); if (!db->open()) return; connect(ui->cmbYear, &QComboBox::currentTextChanged, [=](QString text) { renderComboBoxMonth(); }); connect(ui->cmbMonth, &QComboBox::currentTextChanged, [=](QString text) { renderComboBoxDay(); }); // 默认设置当前操作选择主通道 currentChannel = DatabaseManager::MainChannel; QTimer::singleShot(200, [=] { emit curChannelChanged(Constant::MainChannel); }); } Menu::~Menu() { delete ui; delete db; } /** * @brief 重写菜单show方法 */ void Menu::show() { renderComboBoxYear(); getContents(); QWidget::show(); } /** * @brief 设置是否显示通道选择 * @param visible */ void Menu::setChannelSelectVisible(bool visible) { ui->widget_chnSelect->setVisible(visible); } /** * @brief 渲染年份 */ void Menu::renderComboBoxYear() { QStringList years = db->getAllYears(currentChannel); ui->cmbYear->clear(); for (auto& str : years) { ui->cmbYear->addItem(str); } ui->cmbYear->setCurrentIndex(0); } /** * @brief 渲染月份 */ void Menu::renderComboBoxMonth() { QString year = ui->cmbYear->currentText(); if (year.isEmpty()) { return; } QStringList months = db->getAllMonths(currentChannel, year); ui->cmbMonth->clear(); for (auto& str : months) { ui->cmbMonth->addItem(str); } ui->cmbMonth->setCurrentIndex(0); } /** * @brief 渲染天数 */ void Menu::renderComboBoxDay() { QString year = ui->cmbYear->currentText(); QString month = ui->cmbMonth->currentText(); if (year.isEmpty() || year.isEmpty()) { return; } QStringList days = db->getAllDays(currentChannel, year, month); ui->cmbDay->clear(); for (auto& str : days) { ui->cmbDay->addItem(str); } ui->cmbDay->setCurrentIndex(0); } /** * @brief 获取数据 */ void Menu::getContents() { QVariantMap params; params["channel"] = currentChannel; params["year"] = ui->cmbYear->currentText(); params["month"] = ui->cmbMonth->currentText(); params["day"] = ui->cmbDay->currentText(); contentList = db->get(params); renderContents(); } /** * @brief 将视频名称列表渲染成一堆按钮放到ScrollArea中,6*6 */ void Menu::renderContents() { QGridLayout* layout = qobject_cast(ui->scrollAreaWidgetContents->layout()); // 清除原来的控件防止内存泄漏 QList widgets = ui->scrollAreaWidgetContents->findChildren(); for (QWidget* w : widgets) { delete w; } // 重新生成若干个按钮 for (int i = 0; i < contentList.length(); i++) { // 文件名格式: yyyyMMddhhmmss.mp4,只将时分秒显示到界面上 DatabaseManager::File file = contentList.at(i); QPushButton* btn = new QPushButton(file.time, ui->scrollArea); btn->setProperty("name", file.filename); btn->setMinimumHeight(CONTENT_CELL_HEIGHT); btn->setStyleSheet("QPushButton{border-radius: 5px;}"); btn->setCheckable(true); btn->setAutoExclusive(true); btn->setObjectName(QString("btn_video_%1").arg(i)); int row = i / CONTENT_COLUMN; int column = i % CONTENT_COLUMN; layout->addWidget(btn, row, column); } // 少于36个用空的widget占位置 if (contentList.length() < CONTENT_ROW * CONTENT_COLUMN) { int lastRow = (contentList.length() - 1) / CONTENT_COLUMN; int lastColum = (contentList.length() - 1) % CONTENT_COLUMN; for (int i = lastRow; i < CONTENT_ROW; i++) { for (int j = 0; j < CONTENT_COLUMN; j++) { if (i == lastRow && j <= lastColum) { continue; } QWidget* widget = new QWidget(ui->scrollArea); widget->setMinimumHeight(CONTENT_CELL_HEIGHT); layout->addWidget(widget, i, j); } } } } /** * @brief 移动 * @param direction */ void Menu::move(Direction direction) { QWidget* focusWidget = QApplication::focusWidget(); // 当前焦点是否在展开后的ComboBox上 bool isCmbPopup = (strcmp(focusWidget->metaObject()->className(), "QListView") == 0); // 下拉框展开,则只进行上下选择 if (isCmbPopup) { // 随便赋值一个不影响功能的按键 Qt::Key key = Qt::Key_Right; if (direction == Up) { key == Qt::Key_Up; } else if (direction == Down) { key == Qt::Key_Down; } QKeyEvent pressEvent(QEvent::KeyPress, key, Qt::NoModifier); QApplication::sendEvent(focusWidget, &pressEvent); QKeyEvent releaseEvent(QEvent::KeyRelease, key, Qt::NoModifier); QApplication::sendEvent(focusWidget, &releaseEvent); } else { focusNext(direction); focusWidget = QApplication::focusWidget(); int drawedHeight = focusWidget->visibleRegion().boundingRect().height(); int height = focusWidget->height(); // 绘制的高度小于实际高度,则表示控件显示不完全 if (drawedHeight < height) { ui->scrollArea->ensureWidgetVisible(focusWidget); } if (focusWidget == ui->btnChannelSetting) { ui->btnChannelSetting->setChecked(true); ui->stackedWidget->setCurrentIndex(0); } else if (focusWidget == ui->btnPlayback) { ui->btnPlayback->setChecked(true); ui->stackedWidget->setCurrentIndex(1); } } } /** * @brief 确认 */ void Menu::confirm() { int index = ui->stackedWidget->currentIndex(); QWidget* focusWidget = QApplication::focusWidget(); switch (index) { // 通道设置界面 case 0: { QPushButton* btn = qobject_cast(focusWidget); btn->setChecked(true); if (btn == ui->btn_hdmi_1) { emit btnHdmi1Checked(); } else if (btn == ui->btn_hdmi_2) { emit btnHdmi2Checked(); } else if (btn == ui->btn_vga_1) { emit btnVga1Checked(); } else if (btn == ui->btn_vga_2) { emit btnVga2Checked(); } break; } // 回放界面 case 1: { // 通道选择时按下确认 if (focusWidget == ui->btn_channel_1 || focusWidget == ui->btn_channel_2) { QPushButton* btn = qobject_cast(focusWidget); btn->setChecked(true); if (btn == ui->btn_channel_1) { currentChannel = DatabaseManager::MainChannel; emit curChannelChanged(Constant::MainChannel); } else { currentChannel = DatabaseManager::SecondaryChannel; emit curChannelChanged(Constant::SecondaryChannel); } renderComboBoxYear(); } // 下拉框未展开时按下确认 else if (strcmp(focusWidget->metaObject()->className(), "QComboBox") == 0) { QComboBox* cmb = qobject_cast(focusWidget); cmb->showPopup(); } // 下拉框展开时按下确认 else if (strcmp(focusWidget->metaObject()->className(), "QListView") == 0) { // QComboBox的层级 // QComboBox // |- QComboBoxPrivateContainer(Popup widget) // |- QListView(or QListWidget) // |-QViewPort(Child of QListView) QComboBox* cmb = static_cast(focusWidget->parent()->parent()); if (cmb) { cmb->hidePopup(); } } // 选择视频时按下确认 else if (focusWidget->objectName().contains("btn_video")) { QPushButton* btn = qobject_cast(focusWidget); btn->setChecked(true); QString filename = btn->property("name").toString(); emit btnVideoClicked(filename); currentFilename = filename; } // 确认按钮按下确认 else if (focusWidget->objectName() == "btn_done") { getContents(); } break; } default: break; } } /** * @brief 点击查找当前列表中的上一个视频和下一个视频 */ void Menu::clickVideo(QString type) { getContents(); int index = -1; for (int i = 0; i < contentList.length(); i++) { DatabaseManager::File file = contentList[i]; if (file.filename == currentFilename) { index = i; break; } } QString filename; // 上一个视频 if (type == "previous") { if (index == 0) { emit btnVideoClicked("first"); return; } filename = contentList[index - 1].filename; } // 下一个视频 else { if (index == contentList.length() - 1) { emit btnVideoClicked("last"); return; } filename = contentList[index + 1].filename; } filename = contentList[index + 1].filename; emit btnVideoClicked(filename); QString h = filename.mid(8, 2); QString m = filename.mid(10, 2); QString s = filename.mid(12, 2); QString str = QString("%1:%2:%3").arg(h).arg(m).arg(s); // 选中要播放的按钮 QList btns = ui->scrollArea->findChildren(); for (QPushButton* btn : btns) { if (btn->text() == str) { btn->setChecked(true); } } } /** * @brief 遍历当前窗体可以获取焦点的所有控件 */ QList Menu::getAllFocusabelWidget() { QList list = findChildren(); QList result; for (int i = 0; i < list.length(); i++) { QWidget* w = list.at(i); if (w->focusPolicy() == Qt::NoFocus || !w->isVisible()) continue; else { result.push_back(w); } } return result; }