#include "Menu.h" #include "Channel.h" #include "Constant.h" #include "DatabaseManager.h" #include "Log.h" #include "Tool.h" #include "ui_Menu.h" #include #include #include #include #include extern QList channelList; 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(); ui->cmbYear->setView(new QListView()); ui->cmbMonth->setView(new QListView()); ui->cmbDay->setView(new QListView()); ui->cmbResolutionA->setView(new QListView()); ui->cmbResolutionB->setView(new QListView()); ui->cmbResolutionInA->setView(new QListView()); ui->cmbResolutionInB->setView(new QListView()); ui->timeSlider->setOpacity(0.5); // 默认设置当前操作选择主通道 curSelectChannel = DatabaseManager::MainChannel; db = DatabaseManager::getInstace(); if (!db->open()) return; // 设置ScrollArea为栅格布局 connect(ui->cmbYear, &QComboBox::currentTextChanged, [=](QString text) { renderComboBoxMonth(); }); connect(ui->cmbMonth, &QComboBox::currentTextChanged, [=](QString text) { renderComboBoxDay(); }); for (const auto& chn : channelList) { connect(chn, SIGNAL(appendOneVideo()), this, SLOT(onAppendVideo())); } renderComboBoxYear(); renderTimeSlider(); } Menu::~Menu() { delete ui; } /** * @brief 设置是否显示通道选择 * @param visible */ void Menu::setChannelSelectVisible(bool visible) { channelSelectVisible = visible; ui->widget_chnSelect->setVisible(visible); } /** * @brief 渲染年份 */ void Menu::renderComboBoxYear() { QStringList years = db->getAllYears(curSelectChannel); 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(curSelectChannel, 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(curSelectChannel, year, month); ui->cmbDay->clear(); for (auto& str : days) { ui->cmbDay->addItem(str); } ui->cmbDay->setCurrentIndex(0); } /** * @brief 移动 * @param direction */ void Menu::move(Direction direction) { QWidget* focusWidget = QApplication::focusWidget(); if (!focusWidget) { return; } // 当前焦点是否在展开后的ComboBox上 bool isCmbPopup = (strcmp(focusWidget->metaObject()->className(), "QListView") == 0); bool isTimeSlider = focusWidget->objectName() == "timeSlider"; // 下拉框展开,则只进行上下选择 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 if (isTimeSlider) { switch (direction) { case Left: if (curSegmentIndex > 0) { curSegmentIndex--; int cur = segments[curSegmentIndex].startTime; ui->timeSlider->setCurrent(cur); } break; case Right: if (curSegmentIndex < segments.length() - 1) { curSegmentIndex++; int cur = segments[curSegmentIndex].startTime; ui->timeSlider->setCurrent(cur); } break; case Up: case Down: focusNext(direction); break; default: break; } } else { focusNext(direction); focusWidget = QApplication::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() { QWidget* focusWidget = QApplication::focusWidget(); // 当前操作的是按钮 if (strcmp(focusWidget->metaObject()->className(), "QPushButton") == 0) { QPushButton* btn = qobject_cast(focusWidget); if (btn) { // 选择通道输出类型 if (btn == ui->btn_hdmi_1) { btn->setChecked(true); emit btnHdmi1Checked(); } else if (btn == ui->btn_hdmi_2) { btn->setChecked(true); emit btnHdmi2Checked(); } else if (btn == ui->btn_vga_1) { btn->setChecked(true); emit btnVga1Checked(); } else if (btn == ui->btn_vga_2) { btn->setChecked(true); emit btnVga2Checked(); } // 选择通道 else if (btn == ui->btn_channel_1 || btn == ui->btn_channel_2) { btn->setChecked(true); curSelectChannel = btn == ui->btn_channel_1 ? DatabaseManager::MainChannel : DatabaseManager::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) QListView* listView = static_cast(focusWidget); QComboBox* cmb = static_cast(listView->parent()->parent()); if (cmb) { cmb->setCurrentIndex(listView->currentIndex().row()); cmb->hidePopup(); } } // 选中进度条 else if (focusWidget->objectName() == "timeSlider") { QVariantMap params; params["channel"] = curSelectChannel; params["year"] = ui->cmbYear->currentText(); params["month"] = ui->cmbMonth->currentText(); params["day"] = ui->cmbDay->currentText(); emit btnPlaybackClicked(params, curSegmentIndex); hide(); } // 确认按钮按下确认 else if (focusWidget->objectName() == "btn_done") { renderTimeSlider(); } } /** * @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; } /** * @brief 获取当前正在回放的通道 * @return */ DatabaseManager::Channel Menu::getCurPlayChannel() { return curSelectChannel; } /** * @brief 渲染回放时间轴 */ void Menu::renderTimeSlider() { QVariantMap params; params["channel"] = curSelectChannel; params["year"] = ui->cmbYear->currentText(); params["month"] = ui->cmbMonth->currentText(); params["day"] = ui->cmbDay->currentText(); QList segs = Tool::calTimeSegments(params); if (segs.isEmpty()) { return; } ui->timeSlider->setTimeSegments(segs); ui->timeSlider->setCurrent(segs.front().startTime); segments = segs; curSegmentIndex = 0; } /** * @brief 新录制完一个视频槽函数 */ void Menu::onAppendVideo() { Channel* chn = static_cast(sender()); // 一路回放 if (ui->widget_chnSelect->isVisible()) { DatabaseManager::Channel c = static_cast(curSelectChannel); QString channelName = c == DatabaseManager::MainChannel ? Constant::MainChannel : Constant::SecondaryChannel; if (chn->channelName != channelName) { return; } } // 两路回放 else { if (chn->channelName != Constant::MainChannel) { return; } } // 刷新时间轴中时间片的显示 QVariantMap params; params["channel"] = curSelectChannel; params["year"] = ui->cmbYear->currentText(); params["month"] = ui->cmbMonth->currentText(); params["day"] = ui->cmbDay->currentText(); segments = Tool::calTimeSegments(params); ui->timeSlider->setTimeSegments(segments); } void Menu::on_cmbResolutionB_currentIndexChanged(int index) { emit resolutionOutBChanged(index); } void Menu::on_cmbResolutionA_currentIndexChanged(int index) { emit resolutionOutAChanged(index); } void Menu::moveToCenter() { QWidget* p = static_cast(parent()); if (p) { // 获取父窗体的位置和尺寸 QRect parentGeometry = p->geometry(); // 计算子窗体的居中位置 int x = parentGeometry.left() + (parentGeometry.width() - width()) / 2; int y = parentGeometry.top() + (parentGeometry.height() - height()) / 2; // 移动子窗体到父窗体的中心 QWidget::move(x, y); } } void Menu::show() { QWidget::show(); moveToCenter(); ui->btnChannelSetting->setFocus(); } Menu* Menu::restartUI() { Menu* menu = new Menu(); close(); menu->show(); return menu; } void Menu::on_cmbResolutionInA_currentIndexChanged(const QString& text) { QStringList list = text.split("x"); if (list.count() == 2) { emit resolutionInAChanged(list[0].toInt(), list[1].toInt()); } } void Menu::on_cmbResolutionInB_currentIndexChanged(const QString& text) { QStringList list = text.split("x"); if (list.count() == 2) { emit resolutionInAChanged(list[0].toInt(), list[1].toInt()); } }