commit ec32ae543d187caefdf68e922b60aeef39abe856 Author: wyc <1104749580@qq.com> Date: Tue Jun 16 13:38:08 2026 +0800 首次提交 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b28b04f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,3 @@ + + + diff --git a/CPU传数据给GPU的方式 b/CPU传数据给GPU的方式 new file mode 100644 index 0000000..ba35cc1 --- /dev/null +++ b/CPU传数据给GPU的方式 @@ -0,0 +1,21 @@ + + + +1. Uniform Variables 用于向着色器传递少量的不可变数据,如矩阵、颜色、光源位置等。这些数据在渲染过程中的所有绘制调用中保持不变。 +2. Uniform Buffer Objects (UBOs) 允许将多个 uniform 变量打包到一个缓冲区中,并在一个操作中传输到 GPU。这种方法减少了每次渲染调用时的状态切换和数据传输开销 +3. Shader Storage Buffer Objects (SSBOs) 用于存储大量的可读写数据。适合在着色器中存储和操作大量的结构化数据,如粒子系统数据、计算着色器的中间结果等。 +4. Vertex Buffer Objects (VBOs) 用于存储顶点数据(如位置、法线、纹理坐标等),并将这些数据传输到 GPU +5. Element Buffer Objects (EBOs) 或 Index Buffer Objects (IBOs) 用于存储索引数据,用于索引顶点数据。通常与 VBO 一起使用,以提高绘制效率 +6. Frame Buffers (FBOs) 用于离屏渲染,将渲染结果输出到纹理或渲染缓冲区,而不是直接到屏幕上。 +7. Textures 将图像数据传输到 GPU,并在渲染过程中用于纹理映射 +8. Pixel Buffer Objects (PBOs) 用于异步传输像素数据,可以提高从 CPU 到 GPU 的数据传输性能。 +9. Compute Buffer Objects 在计算着色器中用于存储和处理数据。类似于 SSBOs,但专门用于计算着色器阶段。 +10. Transform Feedback Buffers 用于在图形管线的顶点着色器阶段捕获顶点数据,并在渲染后阶段进行处理或保存 + + + +es_spec_3.2-dual-translated .pdf +p516 Appendix D 附录D 记录了opengl es3.0的新增功能 +p526 Appendix E 附录E 记录了opengl es3.1的新增功能 +p536 Appendix F 附录F 记录了opengl es3.2的新增功能 +p551 Appendix G 附录G 向后兼容性 \ No newline at end of file diff --git a/ci/ci.bat b/ci/ci.bat new file mode 100644 index 0000000..c699bee --- /dev/null +++ b/ci/ci.bat @@ -0,0 +1,10 @@ +@echo off +chcp 65001 +call "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvarsx86_amd64.bat" +set CMAKE_EXECUTABLE="C:\Program Files\JetBrains\CLion\bin\cmake\win\x64\bin\cmake.exe" +set CMAKE_SCRIPT="%CD%/ci_windows.cmake" +%CMAKE_EXECUTABLE% -P %CMAKE_SCRIPT% + + + + diff --git a/ci/ci.sh b/ci/ci.sh new file mode 100644 index 0000000..4525141 --- /dev/null +++ b/ci/ci.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# 调用 cmake 执行 .cmake 文件 +/home/alientek/wyc/clion/bin/cmake/linux/x64/bin/cmake -P ./ci_linux.cmake + +# diff --git a/ci/ci_linux.cmake b/ci/ci_linux.cmake new file mode 100644 index 0000000..93ca641 --- /dev/null +++ b/ci/ci_linux.cmake @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.21) +set(CMAKE_CXX_STANDARD 17) +include(find_cmake_library.cmake) + + +set(CMAKE_EXE "/home/alientek/wyc/clion/bin/cmake/linux/x64/bin/cmake") +#set(MAKE_PROGRAM "/home/alientek/wyc/clion/bin/ninja/linux/x64/ninja") +get_filename_component(SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR} DIRECTORY) + + +_build(Debug linux_aarch64.cmake) +_build(Release linux_aarch64.cmake) +_build(Release linux_amd64.cmake) +_build(Debug linux_amd64.cmake) + + + diff --git a/ci/ci_windows.cmake b/ci/ci_windows.cmake new file mode 100644 index 0000000..ecffd62 --- /dev/null +++ b/ci/ci_windows.cmake @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.21) +set(CMAKE_CXX_STANDARD 17) +include(find_cmake_library.cmake) + + +set(CMAKE_EXE "C:/Program Files/JetBrains/CLion/bin/cmake/win/x64/bin/cmake.exe") +#set(MAKE_PROGRAM "C:/Program Files/JetBrains/CLion/bin/ninja/win/x64/ninja.exe") +get_filename_component(SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR} DIRECTORY) + + +_build(Debug msvc2019.cmake) +_build(Release msvc2019.cmake) + diff --git a/ci/find_cmake_library.cmake b/ci/find_cmake_library.cmake new file mode 100644 index 0000000..4ddb433 --- /dev/null +++ b/ci/find_cmake_library.cmake @@ -0,0 +1,54 @@ +function(_find_directory_upwards start_dir dir_name result_var) + set(current_dir "${start_dir}") + set(FOUND FALSE) + while (NOT FOUND) + # 构造目标目录的完整路径 + set(target_dir "${current_dir}/${dir_name}") + + # 检查目标目录是否存在 + if (EXISTS "${target_dir}") + set(FOUND TRUE) + set(${result_var} "${target_dir}" PARENT_SCOPE) + else () + # 获取上一级目录 + get_filename_component(parent_dir "${current_dir}" DIRECTORY) + + # 如果当前目录和上一级目录相同,则已到达根目录 + if ("${current_dir}" STREQUAL "${parent_dir}") + message(FATAL_ERROR "Directory '${dir_name}' not found upwards from '${start_dir}'") + set(${result_var} "" PARENT_SCOPE) + break() + endif () + + # 更新当前目录为上一级目录 + set(current_dir "${parent_dir}") + endif () + endwhile () +endfunction() + +_find_directory_upwards(.. cmake_library cmake_library_dir) +include(${cmake_library_dir}/main.cmake) + + +function(_build BUILD_TYPE TOOL_CHAIN_FILE) + include(${TOOL_CHAIN_FILE}) + set(CMAKE_BUILD_TYPE ${BUILD_TYPE}) + _get_Architecture_Name(_Architecture_Name) + set(BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}/build/${_Architecture_Name}") + execute_process( + COMMAND "${CMAKE_COMMAND}" + -DCMAKE_BUILD_TYPE=${BUILD_TYPE} + # "-DCMAKE_MAKE_PROGRAM=${MAKE_PROGRAM}" + # -G Ninja + "-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_LIST_DIR}/install/${_Architecture_Name}" + -DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON + -S "${SOURCE_DIR}" + -B ${BUILD_DIR} + ) + execute_process( + COMMAND "${CMAKE_COMMAND}" --build "${BUILD_DIR}" -j 14 + ) + execute_process( + COMMAND "${CMAKE_COMMAND}" --install "${BUILD_DIR}" + ) +endfunction() diff --git a/doc/Butterfly-QEvent.png b/doc/Butterfly-QEvent.png new file mode 100644 index 0000000..fd4954e Binary files /dev/null and b/doc/Butterfly-QEvent.png differ diff --git a/doc/Butterfly-QWidget.png b/doc/Butterfly-QWidget.png new file mode 100644 index 0000000..65eb5bb Binary files /dev/null and b/doc/Butterfly-QWidget.png differ diff --git a/main.cmake b/main.cmake new file mode 100644 index 0000000..aee12fa --- /dev/null +++ b/main.cmake @@ -0,0 +1,34 @@ + + +set(module_dir "${CMAKE_CURRENT_LIST_DIR}/module") +set(dir "${module_dir}/radio") +file(GLOB_RECURSE srcs "${dir}/*.c" "${dir}/*.cpp" "${dir}/*.h" "${dir}/*.hpp") +add_executable(radio ${srcs}) +target_link_libraries(radio PUBLIC YSGraphic_Core) +if(MSVC) + target_compile_definitions(radio PRIVATE MockBackEnd) +endif() +set_property(TARGET radio PROPERTY AUTOMOC ON) +set_property(TARGET radio PROPERTY AUTOUIC ON) +set_property(TARGET radio PROPERTY AUTORCC ON) + + + + + + + + + +#_enable_project(example_qt_runtime_exe Qt5::Widgets Qt5::PrintSupport Qt5::QuickWidgets) +# /opt/atk-dlrk356x-toolchain/aarch64-buildroot-linux-gnu/sysroot/usr/lib/libmali.so +#/opt/atk-dlrk356x-toolchain/aarch64-buildroot-linux-gnu/sysroot/usr/lib/libGLESv1_CM.so +#/opt/atk-dlrk356x-toolchain/aarch64-buildroot-linux-gnu/sysroot/usr/lib/libGLESv2.so +#/opt/atk-dlrk356x-toolchain/aarch64-buildroot-linux-gnu/sysroot/usr/include/GLES2/gl2.h +#/opt/atk-dlrk356x-toolchain/aarch64-buildroot-linux-gnu/sysroot/usr/lib/libGLESv2.so +#/opt/atk-dlrk356x-toolchain/aarch64-buildroot-linux-gnu/sysroot/usr/include +#find_package(OpenGL REQUIRED) + +#alientek@alientek-virtual-machine:~$ cd /opt/atk-dlrk356x-toolchain/aarch64-buildroot-linux-gnu/sysroot/usr/include/GLES3 +#alientek@alientek-virtual-machine:/opt/atk-dlrk356x-toolchain/aarch64-buildroot-linux-gnu/sysroot/usr/include/GLES3$ ls +#gl31.h gl32.h gl3.h gl3platform.h diff --git a/module/F/Center.h b/module/F/Center.h new file mode 100644 index 0000000..d93ba9f --- /dev/null +++ b/module/F/Center.h @@ -0,0 +1,33 @@ +#ifndef CENTER_H +#define CENTER_H +#include "component/Button.h" +#include "global.h" +class Center : public QWidget { +public: + QWidget* cur{}; + Center() = default; + void setWidget(QWidget* widget) { + if (cur) + { + cur->hide(); + } + cur = widget; + widget->setParent(this); + widget->resize(width(), height()); + widget->show(); + } +protected: + void paintEvent(QPaintEvent* event) override { + // QPainter painter(this); + // painter.fillRect(event->rect(), Qt::black); + // painter.end(); + QWidget::paintEvent(event); + } + void resizeEvent(QResizeEvent* event) override { + if (cur) + { + cur->resize(width(), height()); + } + } +}; +#endif diff --git a/module/F/MainWindow.h b/module/F/MainWindow.h new file mode 100644 index 0000000..e3452fa --- /dev/null +++ b/module/F/MainWindow.h @@ -0,0 +1,23 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H +#include "Center.h" +#include "Navigate_Bar.h" +#include "component/frameless/FrameLessWidget.h" +#include "header.h" +class MainWindow : public FrameLessWidget { +public: + QVBoxLayout* main_layout; + Header* header; + QHBoxLayout* center_layout; + Navigate_Bar* navigate_bar; + Center* center; + void create_center_Layout(); + MainWindow(); +protected: + // void paintEvent(QPaintEvent* event) override { + // QPainter painter(this); + // painter.fillRect(rect(), Qt::gray); + // painter.end(); + // } +}; +#endif diff --git a/module/F/Navigate_Bar.h b/module/F/Navigate_Bar.h new file mode 100644 index 0000000..91607c7 --- /dev/null +++ b/module/F/Navigate_Bar.h @@ -0,0 +1,154 @@ +#ifndef Navigate_Bar_H +#define Navigate_Bar_H +#include "function/function.export.h" +#include "global.h" +class Delegate_导航 : public QStyledItemDelegate { +public: + using QStyledItemDelegate::QStyledItemDelegate; + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override { + painter->save(); + auto dd = index.data(Qt::DisplayRole).value<导航_Dat>(); + if (std::holds_alternative<导航_Dat1>(dd.data)) + { + bool selected = option.state & QStyle::State_Selected; + if (selected) + { + painter->setPen(Qt::NoPen); + // painter->setBrush(QColor("#ADD8E6")); + painter->setBrush(base); + painter->drawRoundedRect(option.rect, 4, 4); + } + auto& d = std::get<导航_Dat1>(dd.data); + QColor cc = selected ? Qt::white : d.icon.get_color(); + int height = 20; + int y = (option.rect.height() - height) / 2; + QRect iconRect = QRect(option.rect.left() + 8, option.rect.y() + y, height, height); + d.icon.render(painter, iconRect, cc); + QRect textRect = option.rect; + textRect.setLeft(iconRect.right() + 8); + painter->setPen(QPen(cc)); + painter->drawText(textRect, Qt::AlignVCenter, d.text); + } + if (std::holds_alternative<导航_Dat2>(dd.data)) + { + auto& d = std::get<导航_Dat2>(dd.data); + QRect textRect = option.rect; + // painter->drawRect(textRect); + painter->setPen(QPen(Qt::darkGray)); + painter->setFont(get_font()); + painter->drawText(textRect, Qt::AlignVCenter, d.text); + painter->drawLine(textRect.bottomLeft(), textRect.bottomRight()); + } + painter->restore(); + } + QFont get_font() const { + QFont f; + f.setPixelSize(18); + return f; + } + QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override { + auto dd = index.data(Qt::DisplayRole).value<导航_Dat>(); + if (std::holds_alternative<导航_Dat1>(dd.data)) + { + auto& d = std::get<导航_Dat1>(dd.data); + QString text = d.text; + int width = option.rect.width(); // 视图宽度 + QFontMetrics fm(option.font); // 获取字体度量 + int textHeight = + fm.boundingRect(QRect(0, 0, width, 0), Qt::TextWordWrap, text).height(); // 计算多行文本的高度 + int extraPadding = 10; // 额外的间距 + return QSize(width, textHeight + extraPadding); // 返回计算后的尺寸 + } + if (std::holds_alternative<导航_Dat2>(dd.data)) + { + auto& d = std::get<导航_Dat2>(dd.data); + QString text = d.text; + QFontMetrics fm(get_font()); + int extraPadding = 20; // 额外的间距 + return QSize(fm.horizontalAdvance(text), fm.height() + extraPadding); // 返回计算后的 + } + return {0, 20}; + } +}; +class View_导航 : public QListView { +public: + explicit View_导航(QWidget* parent = nullptr) : QListView(parent) { + setFrameShape(QFrame::NoFrame); + model = new Model_导航<导航_Dat>(this); + QAbstractItemView::setModel(model); + setItemDelegate(new Delegate_导航(this)); + QObject::connect(this, &QListView::clicked, [&](const QModelIndex& index) { + 导航_Dat it = model->data(index, Qt::DisplayRole).value<导航_Dat>(); + if (click) click(&it); + }); + setStyleSheet("background: rgba(0, 0, 0, 0);"); + setSpacing(2); + } +protected: + void paintEvent(QPaintEvent* e) override { + QPainter painter(viewport()); // 在视图区域绘制 + QListView::paintEvent(e); + } +public: + std::function click = nullptr; + QVector<导航_Dat> items; + void update_model() { model->setDataList(items); } +private: + Model_导航<导航_Dat>* model; +}; +class Navigate_Bar : public QWidget { +public: + View_导航* w; + QVBoxLayout* layout; + void set_click(const std::function& click) { w->click = click; } + 采集预处理* m采集预处理; + 信号侦察* m信号侦察; + 信号处理* m信号处理; + 信号生成* m信号生成; + 信号对消* m信号对消; + 存储列表* m存储列表; +protected: + void paintEvent(QPaintEvent* event) override { + QPainter painter(this); + painter.setRenderHints(QPainter::Antialiasing); + painter.setPen(Qt::NoPen); + painter.setBrush(Qt::white); + painter.drawRoundedRect(rect(), 8, 8); + painter.end(); + } +public: + Navigate_Bar() { + layout = new QVBoxLayout(this); + w = new View_导航; + m采集预处理 = new 采集预处理; + m信号侦察 = new 信号侦察; + m信号处理 = new 信号处理; + m信号生成 = new 信号生成; + m信号对消 = new 信号对消; + m存储列表 = new 存储列表; + QColor c = Qt::darkGray; + w->items.push_back(导航_Dat(导航_Dat2{"功能模块"})); + w->items.push_back( + 导航_Dat(导航_Dat1{"采集预处理\n\t\t999.999MHZ", "采集预处理", "F信号 载频、能量、用户聚类", + SVGImage_Render().set_path(":/filter_1.svg").set_color(c).create(), m采集预处理})); + w->items.push_back( + 导航_Dat(导航_Dat1{"信号侦察\n\tF信号侦察\n\t\t\t\t6/44", "信号侦察", "F信号 载频、能量、用户聚类", + SVGImage_Render().set_path(":/filter_2.svg").set_color(c).create(), m信号侦察})); + w->items.push_back( + 导航_Dat(导航_Dat1{"信号处理", "信号处理", "F信号 载频、能量、用户聚类", + SVGImage_Render().set_path(":/filter_3.svg").set_color(c).create(), m信号处理})); + w->items.push_back( + 导航_Dat(导航_Dat1{"信号生成", "信号生成", "F信号 载频、能量、用户聚类", + SVGImage_Render().set_path(":/filter_4.svg").set_color(c).create(), m信号生成})); + w->items.push_back( + 导航_Dat(导航_Dat1{"信号对消", "信号对消", "F信号 载频、能量、用户聚类", + SVGImage_Render().set_path(":/filter_5.svg").set_color(c).create(), m信号对消})); + w->items.push_back(导航_Dat(导航_Dat2{"数据存储"})); + w->items.push_back( + 导航_Dat(导航_Dat1{"存储列表\n\t\t1/60", "存储列表", "F信号 载频、能量、用户聚类", + SVGImage_Render().set_path(":/filter_1.svg").set_color(c).create(), m存储列表})); + w->update_model(); + layout->addWidget(w); + } +}; +#endif // FUNCTION_BAR_H diff --git a/module/F/ScrollBar.cpp b/module/F/ScrollBar.cpp new file mode 100644 index 0000000..82fe1e5 --- /dev/null +++ b/module/F/ScrollBar.cpp @@ -0,0 +1,49 @@ +#include "ScrollBar.h" +#include +#include +#include "function/function_global.h" +void ScrollBar::Style::drawComplexControl(ComplexControl control, const QStyleOptionComplex* option, +QPainter* painter, const QWidget* widget) const { + + painter->fillRect(widget->rect(), Qt::white); + SubControls sub = option->subControls; + if(CC_ScrollBar != control){ + return; + } + const QStyleOptionSlider* sopt = qstyleoption_cast(option); + + // 前面的矩形 + QRect front = subControlRect(control, sopt, QStyle::SC_ScrollBarSubLine, widget); + QRect back = subControlRect(control, sopt, QStyle::SC_ScrollBarAddLine, widget); + + + + // painter->drawRect(leftIndicatorRect); + // painter->drawRect(rightIndicatorRect); + // qDebug() << r2; + // painter->drawRect(r2); + + // if(sub & QStyle::SC_ScrollBarSubLine) { + // QStyleOptionComplex* opt = const_cast(option); + // opt->subControls = QStyle::SC_ScrollBarSubLine; + // QProxyStyle::drawComplexControl(control, option, painter, widget); + // return; + // } + // if(sub & QStyle::SC_ScrollBarSubLine) { + // QStyleOptionComplex* opt = const_cast(option); + // opt->subControls = QStyle::SC_ScrollBarSubLine; + // QProxyStyle::drawComplexControl(control, option, painter, widget); + // return; + // } + + + QRect scrollBarRect = sopt->rect; + painter->setPen(Qt::NoPen); + painter->setBrush(Qt::blue); + //painter->drawRoundedRect(scrollBarRect, 6, 6); + + QRectF sliderRect = subControlRect(control, sopt, QStyle::SC_ScrollBarSlider, widget); + painter->setBrush(base); + painter->drawRoundedRect(sliderRect, 6, 6); + +} \ No newline at end of file diff --git a/module/F/ScrollBar.h b/module/F/ScrollBar.h new file mode 100644 index 0000000..7fee9f7 --- /dev/null +++ b/module/F/ScrollBar.h @@ -0,0 +1,34 @@ +#ifndef SCROLLBAR_H +#define SCROLLBAR_H +#include +#include +#include + + +class ScrollBar : public QScrollBar { +public: + ScrollBar() { setStyle(new Style()); } + class Style : public QProxyStyle { + public: + void drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption* option, QPainter* painter, + const QWidget* widget) const override { + qDebug() << "drawPrimitive == " << element; + QProxyStyle::drawPrimitive(element, option, painter, widget); + } + void drawComplexControl(ComplexControl control, const QStyleOptionComplex* option, QPainter* painter, + const QWidget* widget) const override; + void drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, + const QWidget* widget) const override { + qDebug() << "drawControl == " << element; + QProxyStyle::drawControl(element, option, painter, widget); + } + QRect subElementRect(SubElement element, const QStyleOption* option, const QWidget* widget) const override { + qDebug() << "subElementRect == " << element; + return QProxyStyle::subElementRect(element, option, widget); + } + }; +}; + + + +#endif diff --git a/module/F/Table.cpp b/module/F/Table.cpp new file mode 100644 index 0000000..efb2b2b --- /dev/null +++ b/module/F/Table.cpp @@ -0,0 +1,71 @@ +#include "Table.h" +#include + + +CustomModel::CustomModel(QObject *parent) + : QAbstractTableModel(parent) { + tableData = { + {"Item 1-1", "Item 1-2", "Item 1-3"}, + {"Item 2-1", "Item 2-2", "Item 2-3"}, + {"Item 3-1", "Item 3-2", "Item 3-3"} + }; +} + +int CustomModel::rowCount(const QModelIndex &) const { + return tableData.size(); +} + +int CustomModel::columnCount(const QModelIndex &) const { + return tableData.isEmpty() ? 0 : tableData[0].size(); +} + +QVariant CustomModel::data(const QModelIndex &index, int role) const { + if (!index.isValid()) + return QVariant(); + + if (role == Qt::DisplayRole || role == Qt::EditRole) { + return tableData[index.row()][index.column()]; + } + + return QVariant(); +} + +bool CustomModel::setData(const QModelIndex &index, const QVariant &value, int role) { + if (index.isValid() && role == Qt::EditRole) { + tableData[index.row()][index.column()] = value.toString(); + emit dataChanged(index, index); + return true; + } + return false; +} + +Qt::ItemFlags CustomModel::flags(const QModelIndex &index) const { + if (!index.isValid()) + return Qt::NoItemFlags; + + return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled; +} +CustomTableDelegate::CustomTableDelegate(QObject *parent) : QStyledItemDelegate(parent) {} + +void CustomTableDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { + painter->save(); + + if (index.row() % 2 == 0) { + painter->fillRect(option.rect, QColor(220, 220, 220)); + } else { + painter->fillRect(option.rect, Qt::white); + } + + painter->drawText(option.rect, Qt::AlignCenter, index.data().toString()); + + painter->restore(); +} + +CustomTableView::CustomTableView(QWidget *parent) : QTableView(parent) { + setAlternatingRowColors(true); + setSelectionBehavior(QAbstractItemView::SelectRows); + setSelectionMode(QAbstractItemView::SingleSelection); + horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); +} + + diff --git a/module/F/Table.h b/module/F/Table.h new file mode 100644 index 0000000..6d2e3e1 --- /dev/null +++ b/module/F/Table.h @@ -0,0 +1,44 @@ +#ifndef CUSTOMMODEL_H +#define CUSTOMMODEL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +class CustomModel : public QAbstractTableModel { +public: + explicit CustomModel(QObject *parent = nullptr); + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + Qt::ItemFlags flags(const QModelIndex &index) const override; +private: + QVector> tableData; +}; + +class CustomTableDelegate : public QStyledItemDelegate { +public: + explicit CustomTableDelegate(QObject *parent = nullptr); + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; +}; + + +class CustomTableView : public QTableView { +public: + explicit CustomTableView(QWidget *parent = nullptr); +}; + + + + + +#endif // CUSTOMMODEL_H diff --git a/module/F/Tree_Table.h b/module/F/Tree_Table.h new file mode 100644 index 0000000..5cc6759 --- /dev/null +++ b/module/F/Tree_Table.h @@ -0,0 +1,149 @@ +#ifndef CMAKEUSERPRESETS_JSON_TREE_TABLE_H +#define CMAKEUSERPRESETS_JSON_TREE_TABLE_H +#include +#include +#include +#include +#include +#include +#include +#include "ScrollBar.h" +struct TreeNode { + QStringList data; // 节点数据,每个字段一个字符串 + QList children; // 子节点列表 + TreeNode* parent; // 父节点指针 + + TreeNode(const QStringList& data, TreeNode* parent = nullptr) + : data(data), parent(parent) {} + ~TreeNode() { + qDeleteAll(children); + } +}; + + +class TreeModel : public QAbstractItemModel { +public: + TreeModel(const QStringList& headers, QObject* parent = nullptr) + : QAbstractItemModel(parent), headers(headers) { + rootItem = new TreeNode(headers); + } + + ~TreeModel() { + delete rootItem; + } + + // 必要的虚函数实现 + int rowCount(const QModelIndex& parent = QModelIndex()) const override { + TreeNode* parentNode = nodeFromIndex(parent); + return parentNode->children.count(); + } + + int columnCount(const QModelIndex& parent = QModelIndex()) const override { + return headers.count(); + } + + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override { + if (!index.isValid() || role != Qt::DisplayRole) + return QVariant(); + + TreeNode* item = nodeFromIndex(index); + return item->data.value(index.column()); + } + + QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override { + if (!hasIndex(row, column, parent)) + return QModelIndex(); + + TreeNode* parentNode = nodeFromIndex(parent); + TreeNode* childItem = parentNode->children.value(row); + if (childItem) + return createIndex(row, column, childItem); + else + return QModelIndex(); + } + + QModelIndex parent(const QModelIndex& index) const override { + if (!index.isValid()) + return QModelIndex(); + + TreeNode* childItem = nodeFromIndex(index); + TreeNode* parentItem = childItem->parent; + + if (parentItem == rootItem || !parentItem) + return QModelIndex(); + + int row = parentItem->parent->children.indexOf(parentItem); + return createIndex(row, 0, parentItem); + } + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override { + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) + return headers.value(section); + + return QVariant(); + } + + // 添加节点的函数 + void addNode(const QStringList& data, const QModelIndex& parent = QModelIndex()) { + TreeNode* parentNode = nodeFromIndex(parent); + beginInsertRows(parent, parentNode->children.count(), parentNode->children.count()); + TreeNode* newNode = new TreeNode(data, parentNode); + parentNode->children.append(newNode); + endInsertRows(); + } + +private: + TreeNode* rootItem; + QStringList headers; + + TreeNode* nodeFromIndex(const QModelIndex& index) const { + if (index.isValid()) + return static_cast(index.internalPointer()); + else + return rootItem; + } +}; + + +class TreeDelegate : public QStyledItemDelegate { +public: + TreeDelegate(QObject* parent = nullptr) : QStyledItemDelegate(parent) {} + + QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, + const QModelIndex& index) const override { + // 根据需要创建编辑器,例如 QLineEdit + QLineEdit* editor = new QLineEdit(parent); + return editor; + } + + void setEditorData(QWidget* editor, const QModelIndex& index) const override { + QString value = index.model()->data(index, Qt::EditRole).toString(); + QLineEdit* lineEdit = static_cast(editor); + lineEdit->setText(value); + } + + void setModelData(QWidget* editor, QAbstractItemModel* model, + const QModelIndex& index) const override { + QLineEdit* lineEdit = static_cast(editor); + model->setData(index, lineEdit->text(), Qt::EditRole); + } + + void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, + const QModelIndex& index) const override { + editor->setGeometry(option.rect); + } +}; + + + + +class TreeView : public QTreeView { +public: + TreeView(){ + setVerticalScrollBar(new ScrollBar()); + setHorizontalScrollBar(new ScrollBar()); + } +}; + +#endif + diff --git a/module/F/function/a1_采集预处理.h b/module/F/function/a1_采集预处理.h new file mode 100644 index 0000000..a250917 --- /dev/null +++ b/module/F/function/a1_采集预处理.h @@ -0,0 +1,99 @@ +#ifndef a_采集预处理_H +#define a_采集预处理_H +#include "function_global.h" +class T_采集预处理_瀑布图 : public YSG::Plot { +public: + YSG::FrequentAxis* xAxis{}; + YSG::TimeAxis* yAxis{}; + YSG::MutiSelectRect* msr{}; + YSG::WaterFall* wf{}; + QMenu* mMenu{}; + void init() override { + Plot::init(); + mObjectName = "WaterFallPlot"; + bindRenderThread(mObjectName + "Thread"); + xAxis = YSG::FrequentAxis::Builder(this, Qt::Horizontal).set_tickLength(-10).set_subTickLength(-5).build(); + yAxis = YSG::TimeAxis::Builder(this, Qt::Vertical).build(); + wf = YSG::WaterFall::Builder(xAxis, yAxis).set_layerName("plottable").set_frequentRange({0, 20}).build(); + msr = YSG::MutiSelectRect::Builder(xAxis, yAxis).build(); + } +protected: + void resizeEvent(QResizeEvent* event) override { + xAxis->set_x(0); + xAxis->set_y(height() - 1); + xAxis->set_pixelSize(width()); + yAxis->set_x(0); + yAxis->set_y(0); + yAxis->set_pixelSize(height()); + // wf->set_frequentPointSize(wf->frequentAxis()->getPixelPointSize()); + wf->set_frequentPointSize(width()); + } + void contextMenuEvent(QContextMenuEvent* event) override { + if (!mMenu) + { + auto ws = + bw(cw(wf, -1), "瀑布图") + bw(cw(xAxis), "频率轴") + bw(cw(yAxis), "时间轴") + bw(cw(msr), "多选框"); + mMenu = createMenu(this, ws); + } + mMenu->exec(event->globalPos()); + } +}; +class T_采集预处理_频谱图 : public YSG::Plot { +public: + YSG::FrequentAxis* xAxis{}; + YSG::Axis* yAxis{}; + YSG::MutiSelectRect* msr{}; + YSG::Spectrum* sp{}; + QMenu* mMenu{}; + void init() override { + Plot::init(); + mObjectName = "SpectrumPlot"; + bindRenderThread(mObjectName + "Thread"); + xAxis = YSG::FrequentAxis::Builder(this, Qt::Horizontal) + .set_coordRange({0, 100}) + .set_tickLength(-10) + .set_subTickLength(-5) + .set_use_wheel(true) + .set_use_drag(true) + .build(); + yAxis = YSG::Axis::Builder(this, Qt::Vertical) + .set_coordRange({100, 0}) + .set_unitText("功率") + .set_use_drag(true) + .build(); + sp = YSG::Spectrum::Builder(xAxis, yAxis).set_frequentRange({0, 100}).build(); + msr = YSG::MutiSelectRect::Builder(xAxis, yAxis).build(); + } +protected: + void resizeEvent(QResizeEvent* event) override { + int leftMargin = 20, rightMargin = 20, topMargin = 20, bottomMargin = 20; + int w = width() - leftMargin - rightMargin; + int h = height() - topMargin - bottomMargin; + xAxis->set_x(leftMargin); + xAxis->set_y(height() - bottomMargin); + xAxis->set_pixelSize(w); + yAxis->set_x(leftMargin); + yAxis->set_y(topMargin); + yAxis->set_pixelSize(h); + sp->set_frequentPointSize(sp->frequentAxis()->getPixelPointSize()); + } + void contextMenuEvent(QContextMenuEvent* event) override { + if (!mMenu) + { + auto ws = + bw(cw(sp, -1), "频谱图") + bw(cw(xAxis), "频率x轴") + bw(cw(yAxis), "功率y轴") + bw(cw(msr), "多选框"); + mMenu = createMenu(this, ws); + } + mMenu->exec(event->globalPos()); + } +}; +class 采集预处理 : public BaseWidget { +public: + QHBoxLayout* mainLayout{}; + T_采集预处理_瀑布图* m_瀑布图{}; + T_采集预处理_频谱图* m_频谱图{}; + QVBoxLayout* createV(); + 采集预处理(); + void paintEvent(QPaintEvent* event) override; +}; +#endif diff --git a/module/F/function/a2_信号侦察.h b/module/F/function/a2_信号侦察.h new file mode 100644 index 0000000..9f168b1 --- /dev/null +++ b/module/F/function/a2_信号侦察.h @@ -0,0 +1,62 @@ +#ifndef a_信号侦察_H +#define a_信号侦察_H +#include "function_global.h" +class T_信号侦察_频谱图 : public YSG::Plot { +public: + YSG::FrequentAxis* xAxis{}; + YSG::Axis* yAxis{}; + YSG::MutiSelectRect* msr{}; + YSG::Spectrum* sp{}; + QMenu* mMenu{}; + void init() override { + Plot::init(); + mObjectName = "SpectrumPlot"; + bindRenderThread(mObjectName + "Thread"); + xAxis = YSG::FrequentAxis::Builder(this, Qt::Horizontal) + .set_coordRange({0, 100}) + .set_tickLength(-10) + .set_subTickLength(-5) + .set_use_wheel(true) + .set_use_drag(true) + .build(); + yAxis = YSG::Axis::Builder(this, Qt::Vertical) + .set_coordRange({100, 0}) + .set_unitText("功率") + .set_use_drag(true) + .build(); + sp = YSG::Spectrum::Builder(xAxis, yAxis).set_frequentRange({0, 100}).build(); + msr = YSG::MutiSelectRect::Builder(xAxis, yAxis).build(); + } +protected: + void resizeEvent(QResizeEvent* event) override { + int leftMargin = 20, rightMargin = 20, topMargin = 20, bottomMargin = 20; + int w = width() - leftMargin - rightMargin; + int h = height() - topMargin - bottomMargin; + xAxis->set_x(leftMargin); + xAxis->set_y(height() - bottomMargin); + xAxis->set_pixelSize(w); + yAxis->set_x(leftMargin); + yAxis->set_y(topMargin); + yAxis->set_pixelSize(h); + sp->set_frequentPointSize(sp->frequentAxis()->getPixelPointSize()); + } + void contextMenuEvent(QContextMenuEvent* event) override { + if (!mMenu) + { + auto ws = + bw(cw(sp, -1), "频谱图") + bw(cw(xAxis), "频率x轴") + bw(cw(yAxis), "功率y轴") + bw(cw(msr), "多选框"); + mMenu = createMenu(this, ws); + } + mMenu->exec(event->globalPos()); + } +}; +class 信号侦察 : public BaseWidget { +public: + QHBoxLayout* mainLayout{}; + T_信号侦察_频谱图* m_频谱图{}; + TreeView *treeView{}; + QVBoxLayout* createV(); + void paintEvent(QPaintEvent* event) override; + 信号侦察(); +}; +#endif // 信号侦察_H diff --git a/module/F/function/a3_信号处理.h b/module/F/function/a3_信号处理.h new file mode 100644 index 0000000..d637f16 --- /dev/null +++ b/module/F/function/a3_信号处理.h @@ -0,0 +1,12 @@ +#ifndef a_信号处理_H +#define a_信号处理_H +#include "function_global.h" +class 信号处理 : public BaseWidget { +public: + void paintEvent(QPaintEvent* event) override; + QVBoxLayout* createV(); + QHBoxLayout* mainLayout{}; + TreeView* treeView{}; + 信号处理(); +}; +#endif // 信号处理_H diff --git a/module/F/function/a4_信号生成.h b/module/F/function/a4_信号生成.h new file mode 100644 index 0000000..562f2e2 --- /dev/null +++ b/module/F/function/a4_信号生成.h @@ -0,0 +1,62 @@ +#ifndef a_信号生成_H +#define a_信号生成_H +#include "function_global.h" +class T_信号生成_频谱图 : public YSG::Plot { +public: + YSG::FrequentAxis* xAxis{}; + YSG::Axis* yAxis{}; + YSG::MutiSelectRect* msr{}; + YSG::Spectrum* sp{}; + QMenu* mMenu{}; + void init() override { + Plot::init(); + mObjectName = "SpectrumPlot"; + bindRenderThread(mObjectName + "Thread"); + xAxis = YSG::FrequentAxis::Builder(this, Qt::Horizontal) + .set_coordRange({0, 100}) + .set_tickLength(-10) + .set_subTickLength(-5) + .set_use_wheel(true) + .set_use_drag(true) + .build(); + yAxis = YSG::Axis::Builder(this, Qt::Vertical) + .set_coordRange({100, 0}) + .set_unitText("功率") + .set_use_drag(true) + .build(); + sp = YSG::Spectrum::Builder(xAxis, yAxis).set_frequentRange({0, 100}).build(); + msr = YSG::MutiSelectRect::Builder(xAxis, yAxis).build(); + } +protected: + void resizeEvent(QResizeEvent* event) override { + int leftMargin = 20, rightMargin = 20, topMargin = 20, bottomMargin = 20; + int w = width() - leftMargin - rightMargin; + int h = height() - topMargin - bottomMargin; + xAxis->set_x(leftMargin); + xAxis->set_y(height() - bottomMargin); + xAxis->set_pixelSize(w); + yAxis->set_x(leftMargin); + yAxis->set_y(topMargin); + yAxis->set_pixelSize(h); + sp->set_frequentPointSize(sp->frequentAxis()->getPixelPointSize()); + } + void contextMenuEvent(QContextMenuEvent* event) override { + if (!mMenu) + { + auto ws = + bw(cw(sp, -1), "频谱图") + bw(cw(xAxis), "频率x轴") + bw(cw(yAxis), "功率y轴") + bw(cw(msr), "多选框"); + mMenu = createMenu(this, ws); + } + mMenu->exec(event->globalPos()); + } +}; +class 信号生成 : public BaseWidget { +public: + void paintEvent(QPaintEvent* event) override; + QHBoxLayout* mainLayout{}; + QVBoxLayout* createV(); + TreeView* treeView{}; + T_信号生成_频谱图* m_频谱图{}; + 信号生成(); +}; +#endif // 信号生成_H diff --git a/module/F/function/a5_信号对消.h b/module/F/function/a5_信号对消.h new file mode 100644 index 0000000..f7909b2 --- /dev/null +++ b/module/F/function/a5_信号对消.h @@ -0,0 +1,62 @@ +#ifndef a_信号对消_H +#define a_信号对消_H +#include "function_global.h" +class T_信号对消_频谱图 : public YSG::Plot { +public: + YSG::FrequentAxis* xAxis{}; + YSG::Axis* yAxis{}; + YSG::MutiSelectRect* msr{}; + YSG::Spectrum* sp{}; + QMenu* mMenu{}; + void init() override { + Plot::init(); + mObjectName = "SpectrumPlot"; + bindRenderThread(mObjectName + "Thread"); + xAxis = YSG::FrequentAxis::Builder(this, Qt::Horizontal) + .set_coordRange({0, 100}) + .set_tickLength(-10) + .set_subTickLength(-5) + .set_use_wheel(true) + .set_use_drag(true) + .build(); + yAxis = YSG::Axis::Builder(this, Qt::Vertical) + .set_coordRange({100, 0}) + .set_unitText("功率") + .set_use_drag(true) + .build(); + sp = YSG::Spectrum::Builder(xAxis, yAxis).set_frequentRange({0, 100}).build(); + msr = YSG::MutiSelectRect::Builder(xAxis, yAxis).build(); + } +protected: + void resizeEvent(QResizeEvent* event) override { + int leftMargin = 20, rightMargin = 20, topMargin = 20, bottomMargin = 20; + int w = width() - leftMargin - rightMargin; + int h = height() - topMargin - bottomMargin; + xAxis->set_x(leftMargin); + xAxis->set_y(height() - bottomMargin); + xAxis->set_pixelSize(w); + yAxis->set_x(leftMargin); + yAxis->set_y(topMargin); + yAxis->set_pixelSize(h); + sp->set_frequentPointSize(sp->frequentAxis()->getPixelPointSize()); + } + void contextMenuEvent(QContextMenuEvent* event) override { + if (!mMenu) + { + auto ws = + bw(cw(sp, -1), "频谱图") + bw(cw(xAxis), "频率x轴") + bw(cw(yAxis), "功率y轴") + bw(cw(msr), "多选框"); + mMenu = createMenu(this, ws); + } + mMenu->exec(event->globalPos()); + } +}; +class 信号对消 : public BaseWidget { +public: + void paintEvent(QPaintEvent* event) override; + QHBoxLayout* mainLayout{}; + QVBoxLayout* createV(); + T_信号对消_频谱图* m_频谱图{}; + TreeView *treeView{}; + 信号对消(); +}; +#endif // 信号对消_H diff --git a/module/F/function/a6_存储列表.h b/module/F/function/a6_存储列表.h new file mode 100644 index 0000000..c417e6d --- /dev/null +++ b/module/F/function/a6_存储列表.h @@ -0,0 +1,12 @@ +#ifndef a_存储列表_H +#define a_存储列表_H +#include "function_global.h" +class 存储列表 : public BaseWidget { +public: + void paintEvent(QPaintEvent* event) override; + QHBoxLayout* mainLayout{}; + CustomTableView* m_table{}; + QVBoxLayout* createV(); + 存储列表(); +}; +#endif // 存储列表_H diff --git a/module/F/function/b0_升级记录.h b/module/F/function/b0_升级记录.h new file mode 100644 index 0000000..ef7ae13 --- /dev/null +++ b/module/F/function/b0_升级记录.h @@ -0,0 +1,14 @@ +#include "function_global.h" +#ifndef b0_升级记录_H +#define b0_升级记录_H + + + + +class 升级记录 : QWidget{ +public: + QString content; + Button *confirm{}; +}; + +#endif diff --git a/module/F/function/data_source.cpp b/module/F/function/data_source.cpp new file mode 100644 index 0000000..61488c8 --- /dev/null +++ b/module/F/function/data_source.cpp @@ -0,0 +1,253 @@ +#include "../MainWindow.h" +#include "a2_信号侦察.h" +#include "a3_信号处理.h" +#include "a4_信号生成.h" +#include "a5_信号对消.h" +#include "function.export.h" +#include "a6_存储列表.h" +Data_source data_source; +void Data_source::set_root(MainWindow* root) { m_root = root; } +Data_source::Data_source() {} +// 1 +采集预处理::采集预处理() { + mainLayout = new QHBoxLayout(this); + mainLayout->setMargin(0); + mainLayout->addLayout(createV(), 3); + auto fw = new FunctionWidget(); + auto 中心频率 = create_input("中心频率", "MHZ"); + auto 带宽 = create_input("带宽", "MHZ"); + auto 采样率 = create_input("采样率", "MHZ"); + auto layout = new QVBoxLayout; + layout->setSpacing(0); + layout->addLayout(中心频率); + layout->addSpacing(10); + layout->addLayout(带宽); + layout->addSpacing(10); + layout->addLayout(采样率); + fw->init("预处理参数", "展示设备宽采效果", layout); + mainLayout->addWidget(fw, 1); +} +QVBoxLayout* 采集预处理::createV() { + QVBoxLayout* ret; + ret = new QVBoxLayout(); + m_频谱图 = new T_采集预处理_频谱图; + m_频谱图->init(); + ret->addWidget(m_频谱图); + m_瀑布图 = new T_采集预处理_瀑布图; + m_瀑布图->init(); + ret->addWidget(m_瀑布图); + return ret; +} +void 采集预处理::paintEvent(QPaintEvent* event) { + // QPainter painter(this); + // painter.fillRect(event->rect(), Qt::white); + QWidget::paintEvent(event); +} + +// 2 +QVBoxLayout* 信号侦察::createV() { + auto ret = new QVBoxLayout; + m_频谱图 = new T_信号侦察_频谱图(); + m_频谱图->init(); + ret->addWidget(m_频谱图, 1); + QStringList headers = {"子带通道", "频点", "出联状态", "锁定状态", "出联时间", "出联时长", "符号率", "频值", "EbNo", "误码率", "电平", "帧定时"}; + TreeModel* model = new TreeModel(headers); + QStringList parentData = {"父节点1", "数据2", "数据3"}; + model->addNode(parentData); + QModelIndex parentIndex = model->index(0, 0); + QStringList childData = {"子节点1", "数据2", "数据3"}; + model->addNode(childData, parentIndex); + treeView = new TreeView; + treeView->setModel(model); + TreeDelegate* delegate = new TreeDelegate; + treeView->setItemDelegate(delegate); + treeView->expandAll(); + ret->addWidget(treeView, 1); + return ret; +} + +信号侦察::信号侦察() { + mainLayout = new QHBoxLayout(this); + mainLayout->setMargin(0);mainLayout->setMargin(0); + mainLayout->addLayout(createV(), 3); + auto fw = new FunctionWidget(); + auto layout = new QVBoxLayout; + layout->setSpacing(0); + fw->init("侦察参数", "展示参数信息", layout); + layout->addLayout(create_check_box("载波通道", {"221", "222"})); + layout->addLayout(create_input("中心频率", "MHz")); + layout->addLayout(create_input("带宽", "KHz")); + layout->addLayout(create_input("采样率", "KHz")); + layout->addLayout(create_check_box("调制方式", {"221", "222"})); + layout->addLayout(create_input("符号率", "KBd")); + layout->addLayout(create_check_box("译码方式", {"TPC"})); + mainLayout->addWidget(fw, 1); +} +void 信号侦察::paintEvent(QPaintEvent* event) { + QPainter painter(this); + //painter.fillRect(event->rect(), Qt::yellow); + painter.end(); + QWidget::paintEvent(event); +} + + +// 3 +信号处理::信号处理() { + mainLayout = new QHBoxLayout(this); + mainLayout->setMargin(0); + mainLayout->addLayout(createV(), 3); + auto fw = new FunctionWidget(); + auto layout = new QVBoxLayout; + layout->setSpacing(0); + layout->addLayout(create_check_box("工作模式", {"信号侦察"})); + layout->addLayout(create_check_box("工作模式", {"信号侦察"})); + fw->init("处理参数", "对用户或载波解调译码分析", layout); + mainLayout->addWidget(fw, 1); +} +void 信号处理::paintEvent(QPaintEvent* event) { + QPainter painter(this); + //painter.fillRect(event->rect(), Qt::green); + painter.end(); + QWidget::paintEvent(event); +} +QVBoxLayout* 信号处理::createV() { + QVBoxLayout* ret; + ret = new QVBoxLayout(); + ret->addWidget(new QWidget, 1); + QStringList headers = {"子带通道", "频点", "出联状态", "锁定状态", "出联时间", "出联时长", "符号率", "频值", "EbNo", "误码率", "电平", "帧定时"}; + TreeModel* model = new TreeModel(headers); + QStringList parentData = {"父节点1", "数据2", "数据3"}; + model->addNode(parentData); + QModelIndex parentIndex = model->index(0, 0); + QStringList childData = {"子节点1", "数据2", "数据3"}; + model->addNode(childData, parentIndex); + treeView = new TreeView; + treeView->setModel(model); + TreeDelegate* delegate = new TreeDelegate; + treeView->setItemDelegate(delegate); + treeView->expandAll(); + ret->addWidget(treeView, 1); + return ret; +} + +// 4 +信号生成::信号生成() { + mainLayout = new QHBoxLayout(this); + mainLayout->setMargin(0); + mainLayout->addLayout(createV(), 3); + auto fw = new FunctionWidget(); + auto layout = new QVBoxLayout; + layout->setSpacing(0); + layout->addLayout(create_check_box("发射模式", {"多载波合路"})); + layout->addLayout(create_check_box("数据源", {"本地样本"})); + layout->addLayout(create_check_box("切入点", {"HDLC封装"})); + layout->addLayout(create_check_box("信道编码", {"VIT"})); + // TODO 80比特帧封装 + // TODO 符号映射 + layout->addLayout(create_check_box("调制类型", {"BPSK"})); + layout->addLayout(create_input("发射时刻", {""})); + // TODO 发射样本 + fw->init("生成参数", "支持", layout); + mainLayout->addWidget(fw, 1); +} + +// 4 +void 信号生成::paintEvent(QPaintEvent* event) { + QPainter painter(this); + //painter.fillRect(event->rect(), Qt::red); + painter.end(); + QWidget::paintEvent(event); +} + +QVBoxLayout* 信号生成::createV() { + auto ret = new QVBoxLayout; + m_频谱图 = new T_信号生成_频谱图(); + m_频谱图->init(); + ret->addWidget(m_频谱图, 1); + QStringList headers = {"载波通道", "数据源"}; + TreeModel* model = new TreeModel(headers); + QStringList parentData = {"父节点1", "数据2", "数据3"}; + model->addNode(parentData); + QModelIndex parentIndex = model->index(0, 0); + QStringList childData = {"子节点1", "数据2", "数据3"}; + model->addNode(childData, parentIndex); + treeView = new TreeView; + treeView->setModel(model); + TreeDelegate* delegate = new TreeDelegate; + treeView->setItemDelegate(delegate); + treeView->expandAll(); + ret->addWidget(treeView, 1); + return ret; +} + + +// 5 +信号对消::信号对消() { + mainLayout = new QHBoxLayout(this); +mainLayout->setMargin(0); + mainLayout->addLayout(createV(), 3); + auto fw = new FunctionWidget(); + auto layout = new QVBoxLayout; + layout->setSpacing(0); + layout->addLayout(create_check_box("时差", {"10ms", "20ms"})); + layout->addLayout(create_check_box("频差", {"100Hz"})); + layout->addLayout(create_check_box("搜索范围", {"30ms"})); + fw->init("对消参数", "对40M内发射信号对消", layout); + mainLayout->addWidget(fw, 1); +} +void 信号对消::paintEvent(QPaintEvent* event) { + QPainter painter(this); + //painter.fillRect(event->rect(), Qt::blue); + painter.end(); + QWidget::paintEvent(event); +} + +QVBoxLayout* 信号对消::createV() { + auto ret = new QVBoxLayout; + m_频谱图 = new T_信号对消_频谱图(); + m_频谱图->init(); + ret->addWidget(m_频谱图, 1); + QStringList headers = {"子带通道", "频点", "出联状态", "锁定状态", "出联时间", "出联时长", "符号率", "频值", "EbNo", "误码率", "电平", "帧定时"}; + TreeModel* model = new TreeModel(headers); + QStringList parentData = {"父节点1", "数据2", "数据3"}; + model->addNode(parentData); + QModelIndex parentIndex = model->index(0, 0); + QStringList childData = {"子节点1", "数据2", "数据3"}; + model->addNode(childData, parentIndex); + treeView = new TreeView; + treeView->setModel(model); + TreeDelegate* delegate = new TreeDelegate; + treeView->setItemDelegate(delegate); + treeView->expandAll(); + ret->addWidget(treeView, 1); + return ret; +} +// 6 +存储列表::存储列表() { + mainLayout = new QHBoxLayout(this); +mainLayout->setMargin(0); + mainLayout->addLayout(createV(), 3); + auto fw = new FunctionWidget(); + auto layout = new QVBoxLayout; + layout->setSpacing(0); + layout->addLayout(create_check_box("工作模式", {"信号侦察"})); + layout->addLayout(create_check_box("工作模式", {"信号侦察"})); + fw->init("处理参数", "对用户或载波解调译码分析", layout); + mainLayout->addWidget(fw, 1); +} +void 存储列表::paintEvent(QPaintEvent* event) { + QPainter painter(this); + //painter.fillRect(event->rect(), Qt::gray); + painter.end(); + QWidget::paintEvent(event); +} +QVBoxLayout* 存储列表::createV() { + auto ret = new QVBoxLayout; + m_table = new CustomTableView(this); + auto* model = new CustomModel(this); + auto* delegate = new CustomTableDelegate(this); + m_table->setModel(model); + m_table->setItemDelegate(delegate); + ret->addWidget(m_table); + return ret; +} diff --git a/module/F/function/function.export.h b/module/F/function/function.export.h new file mode 100644 index 0000000..cbd4b95 --- /dev/null +++ b/module/F/function/function.export.h @@ -0,0 +1,19 @@ +#ifndef CMAKEUSERPRESETS_JSON_FUNCTION_EXPORT_H +#define CMAKEUSERPRESETS_JSON_FUNCTION_EXPORT_H +#include "a1_采集预处理.h" +#include "a2_信号侦察.h" +#include "a3_信号处理.h" +#include "a4_信号生成.h" +#include "a5_信号对消.h" +#include "a6_存储列表.h" +#include "b0_升级记录.h" +class MainWindow; +class Data_source { +public: + void set_root(MainWindow* root); + Data_source(); +protected: + MainWindow* m_root{}; +}; +extern Data_source data_source; +#endif diff --git a/module/F/function/function_global.h b/module/F/function/function_global.h new file mode 100644 index 0000000..b9fc525 --- /dev/null +++ b/module/F/function/function_global.h @@ -0,0 +1,88 @@ +#ifndef FUNCTION_GLOBAL_H +#define FUNCTION_GLOBAL_H +#include +#include +#include +#include "DemoGallery/Tool.h" +#include "component/Button.h" +#include "component/ComboBox.h" +#include "component/Input.h" +#include "../Tree_Table.h" +#include "../Table.h" + + +extern QColor base; +class FunctionWidget : public QWidget { +public: + QLabel* title{}; + QLabel* explain{}; + QVBoxLayout* layout{}; + Button* btn{}; + FunctionWidget() {} + void init(const QString& title_text, const QString& explain_text, QLayout* l) { + this->title = new QLabel(title_text); + this->explain = new QLabel(explain_text); + layout = new QVBoxLayout(this); + layout->addLayout(create_line_1()); + btn = new Button(); + btn->content.text = new Text(QString("确定"), QPen(Qt::white)); + layout->addLayout(l); + // qDebug() << " btn->sizeHint() " << btn->sizeHint(); + layout->addStretch(1); + layout->addWidget(btn); + btn->background.set_color(base); + } + QHBoxLayout* create_line_1() { + auto ret = new QHBoxLayout; + ret->addWidget(this->title, 1); + ret->addWidget(this->explain, 1); + return ret; + } + void paintEvent(QPaintEvent* event) override { + QPainter painter(this); + painter.setRenderHints(QPainter::Antialiasing); + painter.setPen(Qt::NoPen); + painter.setBrush(Qt::white); + painter.drawRoundedRect(rect(), 8, 8); + painter.end(); + } +}; +class BaseWidget : public QWidget { +public: +}; +static Button* create_label(const QString& content) { + auto ret = new Button; + ret->content.text = new Text(content); + ret->content.layout.second_prefix = 4; + ret->content.layout.second_suffix = 0; + ret->content.layout.main_type = Layout::Prefix_Space; + // ret->background.set_border(Qt::yellow); + return ret; +} +static QLayout* create_input(const QString& content, const QString& unit) { + auto ret = new QVBoxLayout; + ret->setSpacing(0); + ret->setMargin(0); + auto label = create_label(content); + ret->addWidget(label); + auto core = new Input; + core->unit = unit; + core->focus_color = base; + ret->addWidget(core); + return ret; +} +static QLayout* create_check_box(const QString& content, const QVector& opt_list) { + auto ret = new QVBoxLayout; + ret->setSpacing(0); + ret->setMargin(0); + auto label = create_label(content); + ret->addWidget(label); + auto core = new ComboBox; + for (auto& opt : opt_list) + { + core->addItem(opt); + } + ret->addWidget(core); + return ret; +} +#endif diff --git a/module/F/global.h b/module/F/global.h new file mode 100644 index 0000000..0a971de --- /dev/null +++ b/module/F/global.h @@ -0,0 +1,63 @@ +#ifndef F_GLOBAL_H +#define F_GLOBAL_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "component/SVG.h" +template +class Model_导航 : public QAbstractListModel { +public: + explicit Model_导航(QObject* parent = nullptr) : QAbstractListModel(parent) {} + int rowCount(const QModelIndex& parent = QModelIndex()) const override { return items.size(); } + QVariant data(const QModelIndex& index, int role) const override { + if (!index.isValid() || index.row() >= items.size()) + { + return QVariant(); + } + if (role == Qt::DisplayRole) + { + int i = index.row(); + return QVariant::fromValue(items[i]); + } + return QVariant(); + } + void setDataList(const QVector& dataList) { + beginResetModel(); + items = dataList; + endResetModel(); + } + QVector items; +}; + + + +struct 导航_Dat1 { + QString text; + QString title; + QString detail; + SVGImage_Render icon; + QWidget* widget{}; +}; + +struct 导航_Dat2 { + QString text; +}; + +class 导航_Dat { +public: + 导航_Dat() {} + std::variant<导航_Dat1, 导航_Dat2> data; + 导航_Dat(const std::variant<导航_Dat1, 导航_Dat2>& data) : data(data) {} +}; + + + +Q_DECLARE_METATYPE(导航_Dat) + +#endif diff --git a/module/F/header.h b/module/F/header.h new file mode 100644 index 0000000..c268640 --- /dev/null +++ b/module/F/header.h @@ -0,0 +1,103 @@ +#ifndef HEADER_H +#define HEADER_H +#include "component/Button.h" +#include "global.h" +struct Button; +class Header : public QWidget { +public: + QLabel *icon; + QLabel *app_title; + QLabel *text{}; + QHBoxLayout *layout; + Button *show_update{}; + Switch_Button *max; + Button *hide; + Button *close; + QLabel *cur_title{}; + QLabel *detail{}; + + void set_title(const QString& big_content, const QString& little_content){ + cur_title->setText(big_content); + detail->setText(little_content); + } + explicit Header(QWidget* parent) : QWidget(parent) { + layout = new QHBoxLayout(this); + icon = new QLabel(this); + icon->setPixmap(QPixmap(":/filter_3.svg")); + app_title = new QLabel(this); + QFont app_title_font; + app_title_font.setPointSize(20); + app_title->setFont(app_title_font); + app_title->setText("F信号处理设备"); + app_title->setStyleSheet("color: rgb(255, 255, 255);"); + layout->addWidget(app_title); + + + cur_title = new QLabel("???"); + QFont big_font; + big_font.setPointSize(16); + cur_title->setFont(big_font); + cur_title->setStyleSheet("color: rgb(255, 255, 255);"); + detail = new QLabel("??"); + detail->setStyleSheet("color: rgb(255, 255, 255);"); + + layout->addWidget(icon); + layout->addWidget(app_title); + layout->setSpacing(24); + layout->addWidget(cur_title); + layout->setSpacing(16); + layout->addWidget(detail); + layout->addStretch(); + layout->setMargin(0); + show_update = create_icon(":/help.svg", base, [parent](QEvent::Type t, QMouseEvent* e) { + if (t == QEvent::MouseButtonPress) + { + //parent->showMinimized(); + } + e->accept(); + }); + hide = create_icon(":/zui_xiao_hua.svg", base, [parent](QEvent::Type t, QMouseEvent* e) { + if (t == QEvent::MouseButtonPress) + { + parent->showMinimized(); + } + e->accept(); + }); + max = create_switch_icon( + base, ":/zui_da_hua2.svg", + [parent](QEvent::Type t, QMouseEvent* e) { + parent->showMaximized(); + e->accept(); + }, + ":/zui_da_hua_back.svg", + [parent](QEvent::Type t, QMouseEvent* e) { + parent->showNormal(); + e->accept(); + }); + close = create_icon(":/guan_bi.svg", base, [parent](QEvent::Type t, QMouseEvent* e) { + if (t == QEvent::MouseButtonPress) + { + parent->close(); + } + e->accept(); + }); + layout->addWidget(show_update); + layout->addWidget(hide); + layout->addWidget(max); + layout->addWidget(close); + } +protected: + void resizeEvent(QResizeEvent* event) override { + int a = event->size().height(); + show_update->setFixedSize({a, a}); + hide->setFixedSize({a, a}); + max->setFixedSize({a, a}); + close->setFixedSize({a, a}); + } + void paintEvent(QPaintEvent* event) override { + QPainter painter(this); + // painter.fillRect(event->rect(), Qt::blue); + painter.end(); + } +}; +#endif // HEADER_H diff --git a/module/F/img/1_采集预处理.jpg b/module/F/img/1_采集预处理.jpg new file mode 100644 index 0000000..2ef0dec Binary files /dev/null and b/module/F/img/1_采集预处理.jpg differ diff --git a/module/F/img/2_信号侦察.jpg b/module/F/img/2_信号侦察.jpg new file mode 100644 index 0000000..74c3f38 Binary files /dev/null and b/module/F/img/2_信号侦察.jpg differ diff --git a/module/F/img/3_信号处理.jpg b/module/F/img/3_信号处理.jpg new file mode 100644 index 0000000..ea052f5 Binary files /dev/null and b/module/F/img/3_信号处理.jpg differ diff --git a/module/F/img/4_信号生成.jpg b/module/F/img/4_信号生成.jpg new file mode 100644 index 0000000..6c586fc Binary files /dev/null and b/module/F/img/4_信号生成.jpg differ diff --git a/module/F/img/5_信号对消.jpg b/module/F/img/5_信号对消.jpg new file mode 100644 index 0000000..4f01b59 Binary files /dev/null and b/module/F/img/5_信号对消.jpg differ diff --git a/module/F/img/升级记录.jpg b/module/F/img/升级记录.jpg new file mode 100644 index 0000000..03351f6 Binary files /dev/null and b/module/F/img/升级记录.jpg differ diff --git a/module/F/img/存储列表.jpg b/module/F/img/存储列表.jpg new file mode 100644 index 0000000..841860b Binary files /dev/null and b/module/F/img/存储列表.jpg differ diff --git a/module/F/main.cpp b/module/F/main.cpp new file mode 100644 index 0000000..9de9cd1 --- /dev/null +++ b/module/F/main.cpp @@ -0,0 +1,70 @@ +#include +#include +#ifdef _WINDOWS +#include +#endif +#include +#include +#include +#include "MainWindow.h" +#include "component/SVG.h" +#include "global.h" +// 自定义 qHash 函数 +#include +#include +#include +#include +QColor base = QColor("#007ee1"); +MainWindow::MainWindow() { + background_color = base; + main_layout = new QVBoxLayout(this); + int a = 2; + main_layout->setContentsMargins(leftMargin + 20, topMargin + a, rightMargin + a, bottomMargin + a); + header = new Header(this); + main_layout->addWidget(header); + create_center_Layout(); + data_source.set_root(this); +} + + +void MainWindow::create_center_Layout() { + center_layout = new QHBoxLayout(); + navigate_bar = new Navigate_Bar(); + center_layout->addWidget(navigate_bar, 1); + center = new Center(); + center_layout->addWidget(center, 4); + + main_layout->addSpacing(16); + main_layout->addLayout(center_layout); + + static auto click = [this](导航_Dat* d) { + if(std::holds_alternative<导航_Dat1>(d->data)){ + auto& dd = std::get<导航_Dat1>(d->data); + auto w = dd.widget; + center->setWidget(dd.widget); + header->set_title(dd.title, dd.detail); + } + }; + + navigate_bar->set_click(click); + + click(&navigate_bar->w->items[0]); +} + + +int main(int argc, char* argv[]) { + QApplication app(argc, argv); + QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); +#ifdef _WINDOWS + SetConsoleOutputCP(CP_UTF8); + system("chcp 65001"); + // setbuf(stdout, 0); +#endif + qRegisterMetaType<导航_Dat>("Dat"); + MainWindow w; + w.resize(1000, 700); + w.show(); + // svg/filter_1_24dp_5985E1_FILL0_wght400_GRAD0_opsz24.svg + YSG::startAllRenderThread(); + return QApplication::exec(); +} diff --git a/module/F/mock_data.cpp b/module/F/mock_data.cpp new file mode 100644 index 0000000..9186487 --- /dev/null +++ b/module/F/mock_data.cpp @@ -0,0 +1 @@ +#include "mock_data.h" diff --git a/module/F/mock_data.h b/module/F/mock_data.h new file mode 100644 index 0000000..7aab3f8 --- /dev/null +++ b/module/F/mock_data.h @@ -0,0 +1,4 @@ +#ifndef MOCK_DATA_H +#define MOCK_DATA_H +class mock_data {}; +#endif diff --git a/module/F/resource/order/filter_1.svg b/module/F/resource/order/filter_1.svg new file mode 100644 index 0000000..ad376f2 --- /dev/null +++ b/module/F/resource/order/filter_1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/module/F/resource/order/filter_2.svg b/module/F/resource/order/filter_2.svg new file mode 100644 index 0000000..b7db83e --- /dev/null +++ b/module/F/resource/order/filter_2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/module/F/resource/order/filter_3.svg b/module/F/resource/order/filter_3.svg new file mode 100644 index 0000000..e1dbf7c --- /dev/null +++ b/module/F/resource/order/filter_3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/module/F/resource/order/filter_4.svg b/module/F/resource/order/filter_4.svg new file mode 100644 index 0000000..4f361da --- /dev/null +++ b/module/F/resource/order/filter_4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/module/F/resource/order/filter_5.svg b/module/F/resource/order/filter_5.svg new file mode 100644 index 0000000..af14a76 --- /dev/null +++ b/module/F/resource/order/filter_5.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/module/F/resource/order/filter_6.svg b/module/F/resource/order/filter_6.svg new file mode 100644 index 0000000..0fc371c --- /dev/null +++ b/module/F/resource/order/filter_6.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/module/F/resource/order/filter_7.svg b/module/F/resource/order/filter_7.svg new file mode 100644 index 0000000..a2adc47 --- /dev/null +++ b/module/F/resource/order/filter_7.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/module/F/resource/order/filter_8.svg b/module/F/resource/order/filter_8.svg new file mode 100644 index 0000000..8ccdb63 --- /dev/null +++ b/module/F/resource/order/filter_8.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/module/F/resource/order/filter_9.svg b/module/F/resource/order/filter_9.svg new file mode 100644 index 0000000..bc99a17 --- /dev/null +++ b/module/F/resource/order/filter_9.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/module/F/resource/order/resource.qrc b/module/F/resource/order/resource.qrc new file mode 100644 index 0000000..888abef --- /dev/null +++ b/module/F/resource/order/resource.qrc @@ -0,0 +1,14 @@ + + + filter_1.svg + filter_2.svg + filter_3.svg + filter_4.svg + filter_5.svg + filter_6.svg + filter_7.svg + filter_8.svg + filter_9.svg + + + diff --git a/module/F/resource/other/app.svg b/module/F/resource/other/app.svg new file mode 100644 index 0000000..71ee15c --- /dev/null +++ b/module/F/resource/other/app.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/module/F/resource/other/guan_bi.svg b/module/F/resource/other/guan_bi.svg new file mode 100644 index 0000000..2c9f443 --- /dev/null +++ b/module/F/resource/other/guan_bi.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/module/F/resource/other/help.svg b/module/F/resource/other/help.svg new file mode 100644 index 0000000..a20737f --- /dev/null +++ b/module/F/resource/other/help.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/module/F/resource/other/resource.qrc b/module/F/resource/other/resource.qrc new file mode 100644 index 0000000..b39dd30 --- /dev/null +++ b/module/F/resource/other/resource.qrc @@ -0,0 +1,19 @@ + + + app.svg + zui_da_hua2.svg + help.svg + save.svg + settings.svg + toggle_off.svg + toggle_on.svg + + + + guan_bi.svg + zui_da_hua.svg + zui_da_hua_back.svg + zui_xiao_hua.svg + + + diff --git a/module/F/resource/other/save.svg b/module/F/resource/other/save.svg new file mode 100644 index 0000000..7775492 --- /dev/null +++ b/module/F/resource/other/save.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/module/F/resource/other/settings.svg b/module/F/resource/other/settings.svg new file mode 100644 index 0000000..328e2f0 --- /dev/null +++ b/module/F/resource/other/settings.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/module/F/resource/other/toggle_off.svg b/module/F/resource/other/toggle_off.svg new file mode 100644 index 0000000..3268e82 --- /dev/null +++ b/module/F/resource/other/toggle_off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/module/F/resource/other/toggle_on.svg b/module/F/resource/other/toggle_on.svg new file mode 100644 index 0000000..a706ffd --- /dev/null +++ b/module/F/resource/other/toggle_on.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/module/F/resource/other/zui_da_hua.svg b/module/F/resource/other/zui_da_hua.svg new file mode 100644 index 0000000..d678860 --- /dev/null +++ b/module/F/resource/other/zui_da_hua.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/module/F/resource/other/zui_da_hua2.svg b/module/F/resource/other/zui_da_hua2.svg new file mode 100644 index 0000000..3ac70ef --- /dev/null +++ b/module/F/resource/other/zui_da_hua2.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/module/F/resource/other/zui_da_hua_back.svg b/module/F/resource/other/zui_da_hua_back.svg new file mode 100644 index 0000000..0451db7 --- /dev/null +++ b/module/F/resource/other/zui_da_hua_back.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/module/F/resource/other/zui_xiao_hua.svg b/module/F/resource/other/zui_xiao_hua.svg new file mode 100644 index 0000000..eeb8b23 --- /dev/null +++ b/module/F/resource/other/zui_xiao_hua.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/module/Tree_Table/main.cpp b/module/Tree_Table/main.cpp new file mode 100644 index 0000000..64ac8a6 --- /dev/null +++ b/module/Tree_Table/main.cpp @@ -0,0 +1,129 @@ +#ifndef CUSTOMMODEL_H +#define CUSTOMMODEL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +class CustomModel : public QAbstractTableModel { +public: + explicit CustomModel(QObject *parent = nullptr); + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + Qt::ItemFlags flags(const QModelIndex &index) const override; +private: + QVector> tableData; +}; + +class CustomTableDelegate : public QStyledItemDelegate { +public: + explicit CustomTableDelegate(QObject *parent = nullptr); + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; +}; + + +class CustomTableView : public QTableView { +public: + explicit CustomTableView(QWidget *parent = nullptr); +}; + + + + + +#endif // CUSTOMMODEL_H + + +CustomModel::CustomModel(QObject *parent) + : QAbstractTableModel(parent) { + tableData = { + {"Item 1-1", "Item 1-2", "Item 1-3"}, + {"Item 2-1", "Item 2-2", "Item 2-3"}, + {"Item 3-1", "Item 3-2", "Item 3-3"} + }; +} + +int CustomModel::rowCount(const QModelIndex &) const { + return tableData.size(); +} + +int CustomModel::columnCount(const QModelIndex &) const { + return tableData.isEmpty() ? 0 : tableData[0].size(); +} + +QVariant CustomModel::data(const QModelIndex &index, int role) const { + if (!index.isValid()) + return QVariant(); + + if (role == Qt::DisplayRole || role == Qt::EditRole) { + return tableData[index.row()][index.column()]; + } + + return QVariant(); +} + +bool CustomModel::setData(const QModelIndex &index, const QVariant &value, int role) { + if (index.isValid() && role == Qt::EditRole) { + tableData[index.row()][index.column()] = value.toString(); + emit dataChanged(index, index); + return true; + } + return false; +} + +Qt::ItemFlags CustomModel::flags(const QModelIndex &index) const { + if (!index.isValid()) + return Qt::NoItemFlags; + + return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled; +} +CustomTableDelegate::CustomTableDelegate(QObject *parent) : QStyledItemDelegate(parent) {} + +void CustomTableDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { + painter->save(); + + if (index.row() % 2 == 0) { + painter->fillRect(option.rect, QColor(220, 220, 220)); + } else { + painter->fillRect(option.rect, Qt::white); + } + + painter->drawText(option.rect, Qt::AlignCenter, index.data().toString()); + + painter->restore(); +} + +CustomTableView::CustomTableView(QWidget *parent) : QTableView(parent) { + setAlternatingRowColors(true); + setSelectionBehavior(QAbstractItemView::SelectRows); + setSelectionMode(QAbstractItemView::SingleSelection); + horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); +} + + + +int main(int argc, char *argv[]) { + QApplication app(argc, argv); + + auto *tableView = new CustomTableView; + auto *model = new CustomModel(tableView); + auto *delegate = new CustomTableDelegate(tableView); + + tableView->setModel(model); + tableView->setItemDelegate(delegate); + + tableView->show(); + + + return app.exec(); +} diff --git a/module/main.cpp b/module/main.cpp new file mode 100644 index 0000000..e69de29 diff --git a/module/old/main.cpp b/module/old/main.cpp new file mode 100644 index 0000000..2ffe88a --- /dev/null +++ b/module/old/main.cpp @@ -0,0 +1,240 @@ +#include +#include + +#ifdef _WINDOWS +#include +#include +#endif +#include +#include +#include +#include "GenerateMockData.h" +#include "base/Graphic.h" +#include "base/Plot.h" +#include "component/Table/Table_View.h" +#include "component/Tree/Tree_View.h" +#include "component/simple_widget.h" +#include "plottable/Afterglow.h" +#include "plottable/Planisphere.h" +#include "plottable/Planisphere_p.h" +#include "plottable/Spectrum.h" +#include "plottable/Spectrum_p.h" +#include "plottable/WaterFall.h" +#include "plottable/WaterFall_p.h" +#include "DemoGallery/AfterglowPlot.h" +#include "DemoGallery/DemoGallery.h" +#include "DemoGallery/PlanispherePlot.h" +#include "DemoGallery/SpectrumPlot.h" +#include "DemoGallery/WaterFallPlot.h" + +#include +#include +#include +#include +#include + + +struct TreeNode { + QStringList data; // 节点数据,每个字段一个字符串 + QList children; // 子节点列表 + TreeNode* parent; // 父节点指针 + + TreeNode(const QStringList& data, TreeNode* parent = nullptr) + : data(data), parent(parent) {} + ~TreeNode() { + qDeleteAll(children); + } +}; + + +class TreeModel : public QAbstractItemModel { +public: + TreeModel(const QStringList& headers, QObject* parent = nullptr) + : QAbstractItemModel(parent), headers(headers) { + rootItem = new TreeNode(headers); + } + + ~TreeModel() { + delete rootItem; + } + + // 必要的虚函数实现 + int rowCount(const QModelIndex& parent = QModelIndex()) const override { + TreeNode* parentNode = nodeFromIndex(parent); + return parentNode->children.count(); + } + + int columnCount(const QModelIndex& parent = QModelIndex()) const override { + return headers.count(); + } + + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override { + if (!index.isValid() || role != Qt::DisplayRole) + return QVariant(); + + TreeNode* item = nodeFromIndex(index); + return item->data.value(index.column()); + } + + QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override { + if (!hasIndex(row, column, parent)) + return QModelIndex(); + + TreeNode* parentNode = nodeFromIndex(parent); + TreeNode* childItem = parentNode->children.value(row); + if (childItem) + return createIndex(row, column, childItem); + else + return QModelIndex(); + } + + QModelIndex parent(const QModelIndex& index) const override { + if (!index.isValid()) + return QModelIndex(); + + TreeNode* childItem = nodeFromIndex(index); + TreeNode* parentItem = childItem->parent; + + if (parentItem == rootItem || !parentItem) + return QModelIndex(); + + int row = parentItem->parent->children.indexOf(parentItem); + return createIndex(row, 0, parentItem); + } + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override { + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) + return headers.value(section); + + return QVariant(); + } + + // 添加节点的函数 + void addNode(const QStringList& data, const QModelIndex& parent = QModelIndex()) { + TreeNode* parentNode = nodeFromIndex(parent); + beginInsertRows(parent, parentNode->children.count(), parentNode->children.count()); + TreeNode* newNode = new TreeNode(data, parentNode); + parentNode->children.append(newNode); + endInsertRows(); + } + +private: + TreeNode* rootItem; + QStringList headers; + + TreeNode* nodeFromIndex(const QModelIndex& index) const { + if (index.isValid()) + return static_cast(index.internalPointer()); + else + return rootItem; + } +}; + + +class TreeDelegate : public QStyledItemDelegate { +public: + TreeDelegate(QObject* parent = nullptr) : QStyledItemDelegate(parent) {} + + QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, + const QModelIndex& index) const override { + // 根据需要创建编辑器,例如 QLineEdit + QLineEdit* editor = new QLineEdit(parent); + return editor; + } + + void setEditorData(QWidget* editor, const QModelIndex& index) const override { + QString value = index.model()->data(index, Qt::EditRole).toString(); + QLineEdit* lineEdit = static_cast(editor); + lineEdit->setText(value); + } + + void setModelData(QWidget* editor, QAbstractItemModel* model, + const QModelIndex& index) const override { + QLineEdit* lineEdit = static_cast(editor); + model->setData(index, lineEdit->text(), Qt::EditRole); + } + + void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, + const QModelIndex& index) const override { + editor->setGeometry(option.rect); + } +}; + +class TreeView : public QTreeView{ +public: +}; + +int main(int argc, char* argv[]) { + QApplication app(argc, argv); + // 定义表头 + QStringList headers = {"字段1", "字段2", "字段3"}; + // 创建模型并设置表头 + TreeModel* model = new TreeModel(headers); + // 添加层次化数据 + QStringList parentData = {"父节点1", "数据2", "数据3"}; + model->addNode(parentData); + QModelIndex parentIndex = model->index(0, 0); + QStringList childData = {"子节点1", "数据2", "数据3"}; + model->addNode(childData, parentIndex); + + // 创建视图并设置模型 + TreeView* treeView = new TreeView; + treeView->setModel(model); + + // 设置自定义委托 + TreeDelegate* delegate = new TreeDelegate; + treeView->setItemDelegate(delegate); + + // 展开所有节点 + treeView->expandAll(); + + // 显示窗口 + QMainWindow mainWindow; + mainWindow.setCentralWidget(treeView); + mainWindow.resize(600, 400); + + + mainWindow.show(); + + return app.exec(); +} + + +int main2(int argc, char *argv[]) { + QApplication app(argc, argv); + QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); +#ifdef _WINDOWS + SetConsoleOutputCP(CP_UTF8); + system("chcp 65001"); + //setbuf(stdout, 0); +#endif + QElapsedTimer timer; + timer.start(); + // DemoGallery w; + // w.resize(1000, 600); + // w.show(); + + // YSG::Graphic g; + // g.resize(1000, 600); + // g.show(); + +// auto it = new YSG::SelectColorDialog(); +// it->resize(1000, 600); +// it->show(); + + Tree_View w; + w.resize(400, 400); + w.show(); + + + + YSG::startAllRenderThread(); + qDebug() << "启动耗时 " << timer.elapsed(); + + + + //f(); + + + return QApplication::exec(); +} diff --git a/module/radio/Application.cpp b/module/radio/Application.cpp new file mode 100644 index 0000000..957decf --- /dev/null +++ b/module/radio/Application.cpp @@ -0,0 +1,29 @@ +#include "Application.h" +#include +#include +#include "./BackEnd/MainWidget.h" +#include "BaseWidget.h" +#include "menu/BaseWidgetMenu.h" + +Application::Application(int &argc, char **argv, int flags) : QApplication(argc,argv,flags) { +} + +Application::~Application() = default; + + +bool Application::notify(QObject *object, QEvent *event) { + if( + true + &&event->type() != QEvent::Timer + &&event->type() != QEvent::ZeroTimerEvent + &&event->type() != QEvent::FocusIn + &&event->type() != QEvent::Wheel + &&event->type() != QEvent::KeyPress + ) { + //qDebug() << object << event->type() << event; + } + + + + return QApplication::notify(object, event); +} diff --git a/module/radio/Application.h b/module/radio/Application.h new file mode 100644 index 0000000..cd4ecd3 --- /dev/null +++ b/module/radio/Application.h @@ -0,0 +1,17 @@ +#ifndef Application_H +#define Application_H +#include +#include +class MainWidget; +class Application : public QApplication { +public: + ~Application() override; + bool notify(QObject *object, QEvent *event) override; + MainWidget *mMainWidget; + + explicit Application(int &argc, char **argv, int = ApplicationFlags); +}; +#endif + + + diff --git a/module/radio/BackEnd/BackEnd.cpp b/module/radio/BackEnd/BackEnd.cpp new file mode 100644 index 0000000..11940b4 --- /dev/null +++ b/module/radio/BackEnd/BackEnd.cpp @@ -0,0 +1,2 @@ +#include "BackEnd.h" + diff --git a/module/radio/BackEnd/BackEnd.h b/module/radio/BackEnd/BackEnd.h new file mode 100644 index 0000000..d88bc23 --- /dev/null +++ b/module/radio/BackEnd/BackEnd.h @@ -0,0 +1,37 @@ +#ifndef BackEnd_H +#define BackEnd_H + +#include +#include +#include +#include + +class BackEnd : public QObject { + Q_OBJECT +public: + QMap mFunctionMap; + bool match(QKeyEvent* e, const QString& function); + static BackEnd* instance(); + int YsGetAfGain(); + void YsSetAfGain(int value); + int YsGetRfGain(); + void YsSetRfGain(int value); + qint64 YsGetFreq(); + void YsSetFreq(quint64 value); + void YsReceiveFreq(quint64 freq); + void play(const QString& fileName); + QString get_screenshot_save_dir_path(); + QString get_screenshot_save_file_name(); + QString getAudioFileLocation(); + BackEnd(const BackEnd&) = delete; + BackEnd& operator=(const BackEnd&) = delete; + void callBackData_Func(int channel, void *pData, int iLength); +protected: + BackEnd(); + ~BackEnd() override = default; +}; + +#endif + + + diff --git a/module/radio/BackEnd/BackEnd_Mock.cpp b/module/radio/BackEnd/BackEnd_Mock.cpp new file mode 100644 index 0000000..5bbabae --- /dev/null +++ b/module/radio/BackEnd/BackEnd_Mock.cpp @@ -0,0 +1,153 @@ +#include "BackEnd.h" +#ifdef MockBackEnd +#include "./MainWidget.h" +#include "../component/FrequentShower.h" +#include "../component/ProgressBar.h" +#include "IntermediateFrequencyWidget.h" +#include "RadioWidget.h" +#include "SweepFrequencyWidget.h" + + +void BackEnd::play(const QString& fileName){ + qDebug() << "播放音频文件:" << fileName; +} +QString BackEnd::get_screenshot_save_dir_path() { + return "D:/work/电台保存文件"; +} + +QString BackEnd::get_screenshot_save_file_name() { + QDateTime currentDateTime = QDateTime::currentDateTime(); + return "截屏_" + + currentDateTime.toString() + .replace(":", "_") + .replace("/", "_") + ".png"; +} + + +QString BackEnd::getAudioFileLocation() { + return "D:/work/save/"; +} + +BackEnd *BackEnd::instance() { + static BackEnd temp; + return &temp; +} + +bool BackEnd::match(QKeyEvent *e, const QString &function) { + bool ok = mFunctionMap.contains(function); + if(!ok){ + qDebug() << "error Global::match 失败! 功能" << function << "不存在!" << e; + } + return e->key() == mFunctionMap[function]; +} + +void BackEnd::YsSetFreq(quint64 value) +{ + qDebug() << "后端设置频率为: " << value; +} + + +// 获取到频率 +void BackEnd::YsReceiveFreq(quint64 freq) { + qDebug() << "接收到频率:" << freq; +} + +// 音量设置 +void BackEnd::YsSetAfGain(int value) { + +} + +int BackEnd::YsGetAfGain() { + return 60; +} + +int BackEnd::YsGetRfGain() { + return 60; +} + +qint64 BackEnd::YsGetFreq() { + return 70; +} + + +// 增益设置 +void BackEnd::YsSetRfGain(int value) +{ + +} + + +BackEnd::BackEnd() { + //qDebug() << "BackEnd::BackEnd() " << QThread::currentThreadId(); + mFunctionMap["主菜单"] = Qt::Key_F1; + mFunctionMap["属性菜单"] = Qt::Key_F2; + mFunctionMap["顶部菜单"] = Qt::Key_F3; + mFunctionMap["退出"] = Qt::Key_Escape; + mFunctionMap["确定"] = Qt::Key_Return; + mFunctionMap["左移"] = Qt::Key_Left; + mFunctionMap["右移"] = Qt::Key_Right; + mFunctionMap["增加"] = Qt::Key_Up; + mFunctionMap["减小"] = Qt::Key_Down; + mFunctionMap["切换音量/RF Gain"] = Qt::Key_Return; + mFunctionMap["特别增加"] = Qt::Key_PageUp; + mFunctionMap["特别减小"] = Qt::Key_PageDown; + auto mTimer = new QTimer(this); + + + + QObject::connect(mTimer, &QTimer::timeout, [&](){ + + int size = 1024; + + RadioWidget* rw = MainWidget::instance()->mRadioWidget; + { + auto r = rw->mSpectrogramLine->powerAxis()->coordRange(); + YSG::Range nr = {r.center() - r.length()/4, r.center() + r.length()/4}; + //QVector&& d= YSG::getData(nr, rw->mSpectrogramLine->frequentPointSize()); + QVector&& d= YSG::getData(nr, size); + rw->mSpectrogramLine->giveData(d); + } + { + QVector&& d= YSG::getData(rw->mWaterFall->powerRange(), rw->mWaterFall->frequentPointSize()); + + //qDebug() << "D == " << d.size(); + int tick = rw->mWaterFall->timeAxis()->giveData(QTime::currentTime()); + rw->mWaterFall->giveData(tick, d); + } + { + int tick = rw->mTimePower->timeAxis()->giveData(QTime::currentTime()); + YSG::Range r = rw->mTimePower->valueAxis()->coordRange(); + YSG::Range nr = {r.center() - r.length()/4, r.center() + r.length()/4}; + rw->mTimePower->giveData(tick, YSG::getData(nr)); + } + { + auto r = rw->mAudioSpectrogramPlot->powerAxis()->coordRange(); + YSG::Range nr = {r.center() - r.length()/4, r.center() + r.length()/4}; + //QVector&& d= YSG::getData(nr, rw->mAudioSpectrogramPlot->frequentPointSize()); + QVector&& d= YSG::getData(nr, 512); + rw->mAudioSpectrogramPlot->giveData(d); + } + auto iw = MainWidget::instance()->mIntermediateFrequencyWidget; + { + auto r = iw->mSpectrogramLine->powerAxis()->coordRange(); + YSG::Range nr = {r.center() - r.length()/4, r.center() + r.length()/4}; + //QVector d = YSG::getData(nr, iw->mSpectrogramLine->frequentPointSize()); + QVector d = YSG::getData(nr, size); + iw->mSpectrogramLine->giveData(d); + } + { + //QVector d= YSG::getData(iw->mAfterglow->powerRange(), iw->mAfterglow->frequentPointSize()); + QVector d= YSG::getData(iw->mAfterglow->powerRange(), size); + iw->mAfterglow->giveData(d); + } + auto sw = MainWidget::instance()->mSweepFrequencyWidget; + { + QVector&& sweepData = YSG::getData(sw->mSweepFrequencyLine->powerAxis()->coordRange(), sw->mSweepFrequencyLine->blockFrequentPointSize()); + sw->mSweepFrequencyLine->giveData(sweepData); + } + }); + mTimer->start(10); +} + + +#endif diff --git a/module/radio/BackEnd/BackEnd_True.cpp b/module/radio/BackEnd/BackEnd_True.cpp new file mode 100644 index 0000000..6e2485c --- /dev/null +++ b/module/radio/BackEnd/BackEnd_True.cpp @@ -0,0 +1,337 @@ +#ifndef MockBackEnd + +#include "BackEnd.h" +#include "./MainWidget.h" +#include "../component/FrequentShower.h" +#include "../component/ProgressBar.h" +#include "IntermediateFrequencyWidget.h" +#include "RadioWidget.h" +#include "SweepFrequencyWidget.h" +#include "am_fm_cw_modem.hpp" +#include "device_uhd.h" + +#include // 用于音频文件写入 +#include // 用于音频播放 +#include // Qt 的 QVector +#include +#include +#include +#define BUFFER_SIZE 512 // 缓冲区大小 +Device_UHD* mYsRadio; + +AM_Demod am_demod; +snd_pcm_t *handle; +int err; + +void BackEnd::play(const QString& fileName){ +// mYsRadio->YsSetFreq(value); +} + +BackEnd *BackEnd::instance() { + static BackEnd temp; + return &temp; +} + +bool BackEnd::match(QKeyEvent *e, const QString &function) { + bool ok = mFunctionMap.contains(function); + if(!ok){ + qDebug() << "error Global::match 失败! 功能" << function << "不存在!" << e; + } + return e->key() == mFunctionMap[function]; +} + +void BackEnd::YsSetFreq(quint64 value) +{ + mYsRadio->setDevParam("RX0",UHD_ParamType::CenterFreq,value); + mYsRadio->setDevZDParam("RX0",0,value,150000,300000); +} +qint64 BackEnd::YsGetFreq() { + return (qint64)mYsRadio->getDevParam("RX0",UHD_ParamType::CenterFreq); +} + +// 获取到频率 +void BackEnd::YsReceiveFreq(quint64 freq) { + qDebug() << "接收到频率:" << freq; + MainWidget::instance()->mRadioWidget->mSelectValueWidget->setFrequent(freq); +} + +// 音量设置 +void BackEnd::YsSetAfGain(int value) { + std::string command = "amixer sset Master " + std::to_string(value) + "%"; + int result = system(command.c_str()); + if (result != 0) { + std::cerr << "Failed to set volume: " << result << std::endl; + } +} + +int BackEnd::YsGetAfGain() { + FILE *pipe = popen("amixer sget Master | grep 'Left:' | awk -F'[][]' '{ print $2 }'", "r"); + if (!pipe) { + std::cerr << "Failed to run command" << std::endl; + return -1; + } + + char buffer[128]; + std::string result = ""; + while (!feof(pipe)) { + if (fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + + pclose(pipe); + + // Remove newline character if present + result.erase(std::remove(result.begin(), result.end(), '\n'), result.end()); + + // Convert string to integer + int volume = std::stoi(result); + return volume; +} + +int BackEnd::YsGetRfGain() { + return 60; +} + +// 增益设置 +void BackEnd::YsSetRfGain(int value) +{ + mYsRadio->setDevParam("RX0",UHD_ParamType::Gain,value); + qDebug()<<"增益设置"<DataLen; + //绘图用 + if(pUHDData->DataType == UHD_Enum_DataType::kd_fft ) { + QVector data; + data.clear(); + for(int i = 0; i < 1024; i++) + { + unsigned short ts = *((unsigned short *)pUHDData+32+i); + //qDebug()<<(double) (ts/256); + data.push_back((double) (ts/256)); +// if(i==512) +// {qDebug()<mRadioWidget; + auto iw = mw->mIntermediateFrequencyWidget; + int tick = rw->mWaterFall->timeAxis()->giveData(QTime::currentTime()); + rw->mWaterFall->giveData(tick, data); // 中频瀑布图 + rw->mSpectrogramLine->giveData(data); // 中频频谱图 + + iw->mAfterglow->giveData(data); // 余晖图 + iw->mSpectrogramLine->giveData(data); // 瀑布图 + + + +// auto sl = MainWidget::instance()->mSweepFrequencyWidget->mSweepFrequencyLine; +// int n = sl->blockFrequentPointSize(); +// sl->giveData(data); + + + } + + if(pUHDData->DataType == UHD_Enum_DataType::zd_ddc) + { +// qDebug()<<"收到zd_ddc数据包大小"<DataLen; + + short rbuf[512]; + std::complex* cbuf_ptr = reinterpret_cast*>((char*)pData + 64); + am_demod.step(cbuf_ptr, rbuf, 512); // 解调数据 + + //MainWidget::instance()->mRadioWidget->giv + + QVector data(512); + for(int i = 0; i < 512; ++i){ + data[i] = rbuf[i]; + } + + auto main = MainWidget::instance(); + auto radio = main->mRadioWidget; + + //qDebug() << data; + radio->mAudioSpectrogramPlot->giveData(data); + + //std::cout << "audio == " << rbuf[256] << std::endl; + + int tick = radio->mTimePower->timeAxis()->giveData(QTime::currentTime()); + radio->mTimePower->giveData(tick, rbuf[256]); + + + // 保存音频流 +// ofstream fp_dst; +// fp_dst.open("FM_DeMod.dat", ios::out | ios::binary | ios::app); +// fp_dst.write((char *)rbuf, 512 * 2ll); +// fp_dst.close(); + + +// snd_pcm_writei 是ALSA库提供的函数,用于将音频数据写入PCM设备。 +// handle:指向已打开的PCM设备句柄。 +// buffer:指向包含音频数据的缓冲区。 +// BUFFER_SIZE:要写入的数据帧数。 +// err:存储 snd_pcm_writei 函数的返回值。 +// == -EPIPE:检查返回值是否为 -EPIPE,这表示发生了XRUN(欠载)错误。XRUN发生在音频缓冲区为空时,即音频设备没有足够的数据进行播放。 + + // 播放数据 + if ((err = snd_pcm_writei(handle, rbuf, BUFFER_SIZE)) == -EPIPE) { + fprintf(stderr, "XRUN occurred\n"); + // 重新准备PCM设备 + if ((err = snd_pcm_prepare(handle)) < 0) { + fprintf(stderr, "无法重新准备PCM设备: %s\n", snd_strerror(err)); + } + } else if (err < 0) { + fprintf(stderr, "无法写入音频数据: %s\n", snd_strerror(err)); + } + +// // 关闭音频设备 +// snd_pcm_close(handle); + + } +} + +BackEnd::BackEnd() { + + mFunctionMap["主菜单"] = Qt::Key_F9; + mFunctionMap["属性菜单"] = Qt::Key_F11; + mFunctionMap["顶部菜单"] = Qt::Key_F10; + mFunctionMap["退出"] = Qt::Key_Escape; + mFunctionMap["确定"] = Qt::Key_F2; + mFunctionMap["左移"] = Qt::Key_Left; + mFunctionMap["右移"] = Qt::Key_Right; + mFunctionMap["增加"] = Qt::Key_Up; + mFunctionMap["减小"] = Qt::Key_Down; + mFunctionMap["切换音量/RF Gain"] = Qt::Key_F1; + mFunctionMap["特别增加"] = Qt::Key_PageUp; + mFunctionMap["特别减小"] = Qt::Key_PageDown; + + mYsRadio = new Device_UHD(); + uhd::device_addrs_t tmp_add = mYsRadio->findDevices(); + while(mYsRadio->openDevice(tmp_add[0]) != true) + { + qDebug()<<"9002连接失败,重试中..."; + sleep(1); + mYsRadio->openDevice(tmp_add[0]); + } + qDebug()<<"9002设备连接成功"; + + quint64 value = 10125000; + mYsRadio->setDevParam("RX0",UHD_ParamType::CenterFreq,value); // 宽带设置 + mYsRadio->setDevParam("RX0",UHD_ParamType::BandWidth,100000); // 改带宽,频谱带宽不变 + mYsRadio->setDevParam("RX0",UHD_ParamType::SampleFreq,480000); // 改采样率,频谱带宽变化 + mYsRadio->setDevParam("RX0",UHD_ParamType::Gain,33); +// mYsRadio->setDevDataSwitch("RX0",KDDCSwitch,0,true); + + mYsRadio->setDevFFTParam(UHD_FFTWin::blkmc,_1024,10); // FFT设置 + mYsRadio->setDevDataSwitch("RX0",KFFTSwitch,0,true); + + mYsRadio->setDevZDParam("RX0",0,value,15000,30000); // 窄带设置 + mYsRadio->setDevDataSwitch("RX0",ZDDCSwitch,0, true); + mYsRadio->startDevRecv(0); + + + //mYsRadio->stopDevRecv(0); + + mYsRadio->callBackData = std::bind(&BackEnd::callBackData_Func, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); + +// mYsRadio->hide(); +// connect(mYsRadio, &YsRadio::YsGetFreq, this, &BackEnd::YsReceiveFreq); +// connect(mYsRadio,&YsRadio::YsReceiveSpectrumData,this, &BackEnd::YsReceiveSpectrumData); + + // 打开音频设备 + if ((err = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) { + fprintf(stderr, "无法打开音频设备: %s\n", snd_strerror(err)); + exit(1); + } else{ + qDebug()<<"打开音频设备成功"; + } + + // 设置音频参数 + snd_pcm_hw_params_t *params; + snd_pcm_hw_params_alloca(¶ms); + + // 初始化硬件参数结构 + if ((err = snd_pcm_hw_params_any(handle, params)) < 0) { + fprintf(stderr, "无法初始化硬件参数结构: %s\n", snd_strerror(err)); +// goto close_device; + }else{ + qDebug()<<"初始化硬件参数结构成功"; + } + + // 设置访问类型 + if ((err = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { + fprintf(stderr, "无法设置访问类型: %s\n", snd_strerror(err)); +// goto close_device; + }else{ + qDebug()<<"设置访问类型"; + } + + // 设置样本格式 + if ((err = snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE)) < 0) { + fprintf(stderr, "无法设置样本格式: %s\n", snd_strerror(err)); +// goto close_device; + }else{ + qDebug()<<"设置样本格式"; + } + + // 设置采样率 + unsigned int rate = 30000;//44100 + if ((err = snd_pcm_hw_params_set_rate_near(handle, params, &rate, 0)) < 0) { + fprintf(stderr, "无法设置采样率: %s\n", snd_strerror(err)); +// goto close_device; + }else{ + qDebug()<<"设置采样率"; + } + + // 设置声道数 + if ((err = snd_pcm_hw_params_set_channels(handle, params, 1)) < 0) { + fprintf(stderr, "无法设置声道数: %s\n", snd_strerror(err)); +// goto close_device; + }else{ + qDebug()<<"设置声道数"; + } + + // 应用硬件参数 + if ((err = snd_pcm_hw_params(handle, params)) < 0) { + fprintf(stderr, "无法应用硬件参数: %s\n", snd_strerror(err)); +// goto close_device; + }else{ + qDebug()<<"应用硬件参数"; + } + // 准备播放 + if ((err = snd_pcm_prepare(handle)) < 0) { + fprintf(stderr, "无法准备播放: %s\n", snd_strerror(err)); +// goto close_device; + } else{ + qDebug()<<"准备播放"; + } + +//close_device: +// // 关闭音频设备 +// snd_pcm_close(handle); +} + + + +QString BackEnd::getAudioFileLocation() { + return "./"; +} + +QString BackEnd::get_screenshot_save_file_name() { + QDateTime currentDateTime = QDateTime::currentDateTime(); + return "截屏_" + + currentDateTime.toString() + .replace(":", "_") + .replace("/", "_") + ".png"; +} + +QString BackEnd::get_screenshot_save_dir_path() { + return "/media/sdcard1/"; +} + + +#endif \ No newline at end of file diff --git a/module/radio/BackEnd/IntermediateFrequencyWidget.cpp b/module/radio/BackEnd/IntermediateFrequencyWidget.cpp new file mode 100644 index 0000000..41020e2 --- /dev/null +++ b/module/radio/BackEnd/IntermediateFrequencyWidget.cpp @@ -0,0 +1,328 @@ +#include "IntermediateFrequencyWidget.h" +#include +#include +#include +#include +#include +#include "../component/FrequentShower.h" +#include "../component/ProgressBar.h" +#include "../component/ConsoleWidget.h" +#include "../component/ShowTime.h" +#include "../Global.h" +#include "../BaseWidget.h" +#include "../menu/BaseWidgetMenu.h" +#include "../BackEnd/MainWidget.h" +#include "YSGraphic_Core/DemoGallery/Tool.h" +static YSG::Range frequent_range = {-12000, 12000}; +static double max = 160; +QWidget* IntermediateFrequencyWidget::createSpectrogramPowerPlot() { + class SpectrumPlot : public YSG::Plot { + public: + YSG::FrequentAxis *xAxis{}; + YSG::Axis *yAxis{}; + YSG::MutiSelectRect* msr{}; + YSG::Spectrum *sp{}; + QMenu *mMenu{}; + void init() override { + Plot::init(); + mObjectName = "SpectrumPlot"; + bindRenderThread(mObjectName + "Thread"); + xAxis = YSG::FrequentAxis::Builder(this, Qt::Horizontal) + .set_tickLength(-10) + .set_coordRange(frequent_range) + .set_tickLength(-10) + .set_subTickLength(-5) + + .build(); + + yAxis = YSG::Axis::Builder(this, Qt::Vertical) + .set_coordRange({160, 0}) + .set_unitText("功率") + .build(); + + + sp = YSG::Spectrum::Builder(xAxis, yAxis) + .set_frequentRange(frequent_range) + .set_useSweepFrequentRect(true) + .set_frequentPointSize(1024) + .build(); + + msr = YSG::MutiSelectRect::Builder(xAxis, yAxis).build(); + } + protected: + void resizeEvent(QResizeEvent* event) override { + xAxis->set_x(0); + xAxis->set_y(height() - 1); + xAxis->set_pixelSize(width()); + yAxis->set_x(0); + yAxis->set_y(0); + yAxis->set_pixelSize(height()); + } + void contextMenuEvent(QContextMenuEvent* event) override { + if(!mMenu) { + auto ws = + bw(cw(sp, -1), "频谱图") + + bw(cw(xAxis), "频率x轴") + + bw(cw(yAxis), "功率y轴") + + bw(cw(msr), "多选框"); + mMenu = createMenu(this, ws); + } + mMenu->exec(event->globalPos()); + } + }; + auto w = new SpectrumPlot; + w->init(); + mSpectrogramLine = w->sp; + mProgressBar1->mSetValue = [this]() { + double middleFrequent = this->mSpectrogramLine->frequentRange().center(); + bool ok; + this->mProgressBar1->mValue = mSpectrogramLine->getPower(middleFrequent, ok, YSG::SRC::Cache); + }; + return w; +} + +QWidget* IntermediateFrequencyWidget::create_Afterglow_Plot(){ + class AfterglowPlot : public YSG::Plot { + public: + YSG::FrequentAxis *xAxis{}; + YSG::Axis *yAxis{}; + YSG::Afterglow *ag{}; + YSG::MutiSelectRect* msr{}; + QMenu *mMenu{}; + void init() override { + Plot::init(); + mObjectName = "AfterglowPlot"; + bindRenderThread(mObjectName + "Thread"); + xAxis = YSG::FrequentAxis::Builder(this, Qt::Horizontal) + .set_coordRange(frequent_range) + .set_tickLength(-10) + .set_subTickLength(-5) + .set_use_drag(true) + .build(); + + + + yAxis = YSG::Axis::Builder(this, Qt::Vertical) + .set_coordRange({160, 0}) + .set_use_drag(true) + .build(); + + + ag = YSG::Afterglow::Builder(xAxis, yAxis) + .set_frequentRange(frequent_range) + .set_powerRange({0 , 160}) + .set_frequentPointSize(1024) + .build(); + + + msr = YSG::MutiSelectRect::Builder(xAxis, yAxis).build(); + } + protected: + void resizeEvent(QResizeEvent* event) override { + xAxis->set_x(0); + xAxis->set_y(height() - 1); + xAxis->set_pixelSize(width()); + yAxis->set_x(0); + yAxis->set_y(0); + yAxis->set_pixelSize(height()); + ag->set_powerPointSize(ag->powerAxis()->getPixelPointSize()); + } + void contextMenuEvent(QContextMenuEvent* event) override { + if(!mMenu) { + auto ws = + bw(cw(ag, -1), "余辉图") + + bw(cw(xAxis), "频率轴") + + bw(cw(yAxis),"功率概率轴") + + bw(cw(msr), "多选框"); + mMenu = createMenu(this, ws); + } + mMenu->exec(event->globalPos()); + } + }; + auto w = new AfterglowPlot; + w->init(); + mAfterglow = w->ag; + return w; +} + + +//mAM, mATU, mVSQL, mNB, mNR, mDNF, mPRE, mATT, mSPL, mFIL1, mAGC_A +IntermediateFrequencyWidget::IntermediateFrequencyWidget(QWidget *parent) : BaseWidget(parent) { + setObjectName("发射界面"); + int fontSize = 20; + m1 = createNormal("RF Gain\n62", fontSize); + m2 = createNormal("FFT SPAN\n100K", fontSize); + m3 = createNormal("频率表\n(12)89.6MHZ", fontSize); + m4 = createNormal("MODEM\nRTTY", fontSize); + m5 = createNormal("FIL1\n20K", fontSize); + m6 = createNormal("MSG1\n", fontSize); + mFrequentShower = new FrequentShower(this); + QColor orange(255, 165, 0); + mProgressBar1 = new ProgressBar({ + Tick("S", Qt::black), + {"3", Qt::black}, + {"6", Qt::black}, + {"9", Qt::black}, + {"20", Qt::black}, + {"+40", orange}, + {"+60", orange}, + {"+80", orange}, + {"+100", Qt::red}, + }, this); + mProgressBar2 = new ProgressBar({ + {"1", Qt::black}, + {"2", Qt::yellow}, + {"3", Qt::red}, + {">5", Qt::red}, + }, this); + + + auto main = createVBoxLayout({}, this); + main->addStretch(1); + { + auto center = createHBoxLayout(); + main->addLayout(center, 7); + auto front = createVBoxLayout(); + center->addLayout(front, 1); + front->addWidget(m1, 3); + front->addStretch(1); + front->addWidget(m2, 3); + center->addSpacing(4); + auto middle = createVBoxLayout(); + center->addLayout(middle, 9); + middle->addStretch(1); + middle->addWidget(mFrequentShower, 4); + auto middleH = createHBoxLayout(); + middle->addLayout(middleH, 2); + middleH->addWidget(mProgressBar1, 5); + middleH->addStretch(1); + middleH->addWidget(mProgressBar2, 3); + center->addStretch(4); + auto back1 = createVBoxLayout(); + center->addLayout(back1, 1); + back1->addWidget(m3, 3); + back1->addStretch(1); + back1->addWidget(m4, 3); + center->addSpacing(4); + auto back2 = createVBoxLayout(); + center->addLayout(back2, 1); + back2->addWidget(m5, 3); + back2->addStretch(1); + back2->addWidget(m6, 3); + } + main->addStretch(1); + main->addSpacing(8); + auto aH = createHBoxLayout(); + main->addLayout(aH, 12); + aH->addWidget(createSpectrogramPowerPlot(), 12); + aH->addSpacing(8); + main->addWidget(create_Afterglow_Plot(), 12); + + initMenu(); +} + +IntermediateFrequencyWidget::~IntermediateFrequencyWidget() { +} + +void IntermediateFrequencyWidget::focusInEvent(QFocusEvent *event) { + QWidget::focusInEvent(event); + mFrequentShower->setFocus(); +} + +void IntermediateFrequencyWidget::initMenu() { + int fontSize = 30; + auto btn1 = new DoubleTextMenuButton("设置最大值标记", "取消最大值标记", fontSize, [&](bool isFirst){ + mSpectrogramLine->set_useMaxMarker(isFirst); + mBaseWidgetMenu->hide(); + MainWidget::instance()->getCurrentBaseWidget()->setFocus(); + }); + + auto btn2 = new DoubleTextMenuButton("设置最小值标记", "取消最小值标记", fontSize, [&](bool isFirst){ + mSpectrogramLine->set_useMinMarker(isFirst); + mBaseWidgetMenu->hide(); + MainWidget::instance()->getCurrentBaseWidget()->setFocus(); + }); + + auto btn3 = new MenuButton("设置自定义标记", fontSize, [&](){ + mBaseWidgetMenu->hide(); + MainWidget::instance()->getCurrentBaseWidget()->setFocus(); + }); + + auto frequentStep2 = new ValueMenuButton("频率步进:%1", fontSize, [this](ValueMenuButton* that, bool add){ + int newFrequent = (int)that->mValue + (add?1:-1); + that->setValue(newFrequent); + mSpectrogramLine->setCurrentMarkerFrequent(newFrequent); + }, qMax(0.0, mSpectrogramLine->frequentRange().length()/50.0)); + auto btn_middleFrequent = new ValueMenuButton("中频:%1 Hz", fontSize, nullptr, mSpectrogramLine->middleSweepFrequent()); + auto btn_frequentWidth = new ValueMenuButton("频宽:%1 Hz", fontSize, [this, frequentStep2](ValueMenuButton* that, bool add){ + that->setValue(that->mValue + (double)(add?frequentStep2->mValue:-frequentStep2->mValue)); + double middleSweepFrequent = mSpectrogramLine->middleSweepFrequent(); + mSpectrogramLine->set_sweepFrequentRange({middleSweepFrequent - that->mValue, middleSweepFrequent + that->mValue}); + }, qAbs(mSpectrogramLine->sweepFrequentRange().length()/2)); + + btn_middleFrequent->mValueChanged = [this, btn_frequentWidth, frequentStep2](ValueMenuButton* that, bool add){ + that->setValue(that->mValue + (double)(add?frequentStep2->mValue:-frequentStep2->mValue)); + mSpectrogramLine->set_middleSweepFrequent(that->mValue); + mSpectrogramLine->set_sweepFrequentRange({that->mValue - btn_frequentWidth->mValue, that->mValue + btn_frequentWidth->mValue}); + }; + + auto btn2_2 = new ValueMenuButton("参考增益:%1", fontSize, [&](ValueMenuButton* that, bool add){ + that->setValue(that->mValue + (double)(add ? 1 : -1)); + }, 0); + + mBaseWidgetMenu->addMenuButtonOnLayout1({btn1, btn2, btn3, btn2_2, }); + mBaseWidgetMenu->addMenuButtonOnLayout2({frequentStep2, btn_middleFrequent, btn_frequentWidth,}); + + BaseWidgetMenu* sub1 = mBaseWidgetMenu->createSubWidgetMenu(btn3); + + + auto frequentStep = new ValueMenuButton("频率步进:%1", fontSize, [this](ValueMenuButton* that, bool add){ + int newFrequent = (int)that->mValue + (add?1:-1); + that->setValue(newFrequent); + mSpectrogramLine->setCurrentMarkerFrequent(newFrequent); + }, qMax(0.0, mSpectrogramLine->frequentRange().length()/50.0)); + + auto markFrequent = new ValueMenuButton("更改标记频率:%1", fontSize, [frequentStep, this](ValueMenuButton* that, bool add){ + int newFrequent = (int)that->mValue + (add?frequentStep->mValue:-frequentStep->mValue); + that->setValue(newFrequent); + mSpectrogramLine->setCurrentMarkerFrequent(newFrequent); + }, -1); + + auto addInitFrequent = new ValueMenuButton("添加初始频率:%1", fontSize, [frequentStep,this](ValueMenuButton* that, bool add){ + int newFrequent = (int)that->mValue + (add?frequentStep->mValue:-frequentStep->mValue); + that->setValue(newFrequent); + }, mSpectrogramLine->frequentRange().lower); + + auto btn1_1 = new ValueMenuButton("当前标记:%1", fontSize, [&, markFrequent](ValueMenuButton* that, bool add){ + int index = ((int)that->mValue + (add?1:-1) ) % mSpectrogramLine->selectLineMarkerSize(); + that->setValue(index); + mSpectrogramLine->setSelectedLineMarker(index); + markFrequent->setValue(mSpectrogramLine->getMarkFrequent(index)); + }, -1); + + auto btn1_2 = new MenuButton("添加标记", fontSize, [&, addInitFrequent](){ + mSpectrogramLine->addCustomLineMarker(addInitFrequent->mValue); + }); + auto btn1_3 = new MenuButton("删除标记", fontSize, [&](){ + mSpectrogramLine->removeCurrentMarker(); + int size = mSpectrogramLine->selectLineMarkerSize(); + if(size == 0){ + mSpectrogramLine->setSelectedLineMarker(-1); + } else { + mSpectrogramLine->setSelectedLineMarker(0); + } + }); + connect(sub1, &BaseWidgetMenu::showThat, [&, markFrequent](){ + mSpectrogramLine->setSelectedLineMarker(0); + markFrequent->setValue(mSpectrogramLine->getMarkFrequent(0)); + }); + connect(sub1, &BaseWidgetMenu::hideThat, [&](){ + mSpectrogramLine->unSelectMarker(); + }); + sub1->addMenuButtonOnLayout1({btn1_1, btn1_2, btn1_3},2); + sub1->addMenuButtonOnLayout2({frequentStep, markFrequent, addInitFrequent}, 2); +} + + + + diff --git a/module/radio/BackEnd/IntermediateFrequencyWidget.h b/module/radio/BackEnd/IntermediateFrequencyWidget.h new file mode 100644 index 0000000..468876d --- /dev/null +++ b/module/radio/BackEnd/IntermediateFrequencyWidget.h @@ -0,0 +1,31 @@ +#ifndef IntermediateFrequencyWidget_H +#define IntermediateFrequencyWidget_H +#include "../BaseWidget.h" + +class TextButton; +class DoubleTextButton; +class FrequentShower; +class ProgressBar; +class ConsoleWidget; +class ShowTime; +class BaseWidgetMenu; +class IntermediateFrequencyWidget : public BaseWidget { + Q_OBJECT +public: + explicit IntermediateFrequencyWidget(QWidget *parent = nullptr); + ~IntermediateFrequencyWidget() override; + QPushButton *m1, *m2, *m3, *m4, *m5, *m6; + FrequentShower *mFrequentShower; + ProgressBar *mProgressBar1, *mProgressBar2; + YSG::Spectrum *mSpectrogramLine{}; + YSG::Afterglow *mAfterglow{}; + QWidget* createSpectrogramPowerPlot(); + QWidget* create_Afterglow_Plot(); + void initMenu(); +protected: + void focusInEvent(QFocusEvent *event) override; +}; +#endif + + + diff --git a/module/radio/BackEnd/MainWidget.cpp b/module/radio/BackEnd/MainWidget.cpp new file mode 100644 index 0000000..c895a05 --- /dev/null +++ b/module/radio/BackEnd/MainWidget.cpp @@ -0,0 +1,310 @@ +#include "MainWidget.h" +#include "../component/FrequentShower.h" +#include "../component/TopMenuBar.h" +#include "../menu/BaseWidgetMenu.h" +#include "../subWidget/ServerSettingWidget.h" +#include "IntermediateFrequencyWidget.h" +#include "RadioWidget.h" +#include "SweepFrequencyWidget.h" +#include "YSGraphic_Core/base/export.h" +#include +#include + +#include "../FileDialog/FileExplorer.h" +MainWidget::MainWidget(QWidget *parent) : QWidget(parent) { + setFocusPolicy(Qt::FocusPolicy::NoFocus); + setObjectName("主界面"); + audioRecorder = new QAudioRecorder(this); + audioRecorder->setAudioInput(audioRecorder->defaultAudioInput()); + QAudioEncoderSettings audioSettings; + audioSettings.setCodec("audio/pcm"); + audioSettings.setQuality(QMultimedia::HighQuality); + audioSettings.setSampleRate(44100); // 设置采样率 + audioSettings.setChannelCount(2); // 设置立体声 + audioRecorder->setAudioSettings(audioSettings); + + mediaPlayer = new QMediaPlayer(this); + + + mMainLayout = new QVBoxLayout(this); + mMainLayout->setMargin(8); + mMainLayout->setSpacing(0); + mTopMenuBar = new TopMenuBar(); + mMainLayout->addWidget(mTopMenuBar, 1); + mRadioWidget = new RadioWidget; + mSweepFrequencyWidget = new SweepFrequencyWidget; + mIntermediateFrequencyWidget = new IntermediateFrequencyWidget; + mMainLayout->addWidget(mRadioWidget, 31); + mMainLayout->addWidget(mSweepFrequencyWidget, 31); + mMainLayout->addWidget(mIntermediateFrequencyWidget, 31); + mMainMenu = new BaseWidgetMenu(this); + mMainMenu->setObjectName("主菜单"); + mTopMenu = new BaseWidgetMenu(this); + mTopMenu->setObjectName("顶部菜单"); + mServerSettingWidget = new ServerSettingWidget(this); + showRadioWidget(); + int fontSize = 30; + auto btn11 = new MenuButton("电台模式", fontSize, [&]() { + showRadioWidget(); + mMainMenu->hide(); + }); + + auto btn12 = new MenuButton("中频模式", fontSize, [&]() { + showIntermediateFrequencyWidget(); + mMainMenu->hide(); + }); + + auto btn13 = new MenuButton("扫频模式", fontSize, [&]() { + showSweepFrequencyWidget(); + mMainMenu->hide(); + }); + + auto btn14 = new MenuButton("服务端设置", fontSize, [&]() { + mMainMenu->hide(); + showServerSettingWidget(); + }); + mSelectShotScreenDialog = new FileExplorer(); + // mSelectShotScreenDialog->setGeometry(QApplication::primaryScreen()->geometry()); + // mSelectShotScreenDialog->setAcceptMode(QFileDialog::AcceptSave); + // mSelectShotScreenDialog->setOption(QFileDialog::DontUseNativeDialog, false); + + auto btn15 = new MenuButton("截屏", fontSize, [&]() { + QTimer::singleShot(500, [this]() { + QPixmap pixmap = this->grab(); + auto be = BackEnd::instance(); + QString savePath = be->get_screenshot_save_dir_path() + be->get_screenshot_save_file_name(); + if(pixmap.save(savePath)) { + qDebug() << "Screenshot saved successfully at" << savePath; + } + else { + qDebug() << "Failed to save screenshot at" << savePath; + } + }); + // hideCurHoverWidget(); + // mCurrentHoverWidget = mSelectShotScreenDialog; + // mMainMenu->hide(); + // QString defaultFileName = "截屏" + QDateTime::currentDateTime().toString("yyyy年MM月dd日_hh:mm:ss"); + // mSelectShotScreenDialog->selectFile(BackEnd::instance()->getScreenshotPath() + defaultFileName + ".png"); + // mSelectShotScreenDialog->setFocus(); + // mSelectShotScreenDialog->show(); + // if(mSelectShotScreenDialogFirst){ + // mSelectShotScreenDialogFirst = false; + // auto that = mSelectShotScreenDialog->findChild(); + // if(that){ + // Toolbox::VirtualKeyBoard::instance()->setEdit(that); + // qDebug() << "设置成功!"; + // } + // } + // + // connect(mSelectShotScreenDialog, &QFileDialog::fileSelected, [&](const QString &filePath) { + // QPixmap pixmap = this->grab(); + // if (pixmap.save(filePath)) { + // qDebug() << "截屏保存到了" << filePath; + // } else { + // qDebug() << "截屏保存失败,路径不对" << filePath; + // } + // }); + }); + + auto be = BackEnd::instance(); + mSelectAudioFile = new FileExplorer(); + mSelectAudioFile->setParent(this); + mSelectAudioFile->hide(); + mSelectAudioFile->setObjectName("选择音频文件播放"); + mSelectAudioFile->changeRoot(be->getAudioFileLocation()); + + connect(mSelectAudioFile->cancelButton, &QPushButton::clicked, [this]() { + qDebug() << "播放音频已取消!"; + MainWidget::instance()->getCurrentBaseWidget()->setFocus(); + mSelectAudioFile->hide(); + }); + connect(mSelectAudioFile->confirmButton, &QPushButton::clicked, [this]() { + QString path = mSelectAudioFile->focus.absoluteFilePath(); + if(!path.endsWith(".wav")){ + qWarning() << "选择的文件结尾不是wav 选择的文件为" + path; + } + mediaPlayer->setMedia(QUrl::fromLocalFile(path)); + mediaPlayer->play(); + MainWidget::instance()->getCurrentBaseWidget()->setFocus(); + mSelectAudioFile->hide(); + }); + auto btn21 = new MenuButton("播放音频", fontSize, [this]() { + mSelectAudioFile->setGeometry(rect()); + mSelectAudioFile->show(); + mSelectAudioFile->setFocus(); + // qDebug() << "2222222222222222"; + setCurrentHoverWidget(mSelectAudioFile); + // qDebug() << "2222222222222222"; + }); + + + auto btn22 = new MenuButton("打卡sdk卡", fontSize, [&](){ + + }); + auto btn23 = new DoubleTextMenuButton("开始录音", "停止录音", fontSize, [&](bool isFirst){ + if(isFirst) { + QString wav_path = "file:///" + QString(be->getAudioFileLocation() + "%1.wav").arg( + QDateTime::currentDateTime().toString("yyyy-MM-dd_HH-mm-ss")); + audioRecorder->setOutputLocation(wav_path); + if (audioRecorder->audioInput().isEmpty()) { + qDebug() << "没有找到音频输入设备!"; + } else { + qDebug() << "音频输入设备已设置。audioInput:" + audioRecorder->audioInput() +" path:" + wav_path; + } + audioRecorder->record(); + } else { + qDebug() << "停止录音" << audioRecorder->error() << audioRecorder->errorString(); + audioRecorder->stop(); + } + }); + + auto btn24 = new DoubleTextMenuButton("开始发射", "停止发射", fontSize, [&](bool isFirst){ + if(isFirst){ + + } else { + + } + }); + mMainMenu->addMenuButtonOnLayout1({btn11, btn12, btn13, btn14, btn15}); + mMainMenu->addMenuButtonOnLayout2({btn21, btn22, btn23, btn24}, 1); + + + + auto btnt21 = new MenuButton("PRE", fontSize, [&]() { + qDebug() << "PRE 按下"; + }); + auto btnt22 = new MenuButton("ATT", fontSize, [&]() { + qDebug() << "PRE 按下"; + }); + mTopMenu->addMenuButtonOnLayout1({btnt21, btnt22}, 3); + + +#ifndef MockBackEnd + showFullScreen(); +#else + showMaximized(); +#endif +} + +void MainWidget::paintEvent(QPaintEvent *event) { + QPainter painter(this); + //qDebug() << "MainWidget::paintEvent" ; + //painter.fillRect(rect(), Qt::red); + painter.end(); +} + +void MainWidget::showIntermediateFrequencyWidget() const { + mSweepFrequencyWidget->hide(); + mRadioWidget->hide(); + mIntermediateFrequencyWidget->show(); + mIntermediateFrequencyWidget->setFocus(); +} + +void MainWidget::showSweepFrequencyWidget() const { + mIntermediateFrequencyWidget->hide(); + mRadioWidget->hide(); + mSweepFrequencyWidget->show(); + mSweepFrequencyWidget->setFocus(); +} + +void MainWidget::showRadioWidget() const { + mIntermediateFrequencyWidget->hide(); + mSweepFrequencyWidget->hide(); + mRadioWidget->show(); + mRadioWidget->setFocus(); +} + +void MainWidget::showServerSettingWidget(){ + mServerSettingWidget->raise(); + mServerSettingWidget->show(); + mServerSettingWidget->setFocus(); + setCurrentHoverWidget(mServerSettingWidget); + +} + +BaseWidget *MainWidget::getCurrentBaseWidget() const { + if (mRadioWidget->isVisible()) return mRadioWidget; + else if (mSweepFrequencyWidget->isVisible()) return mSweepFrequencyWidget; + else return mIntermediateFrequencyWidget; +} + + +void MainWidget::setCurrentHoverWidget(QWidget* widget) { + qDebug() << "setCurrentHoverWidget pre" << ( mCurrentHoverWidget ? mCurrentHoverWidget->objectName() : "nullptr"); + qDebug() << "setCurrentHoverWidget set" << ( widget ? widget->objectName() : "nullptr"); + if(mCurrentHoverWidget) { + mCurrentHoverWidget->hide(); + } + mCurrentHoverWidget = widget; +} + + + +void MainWidget::hideCurHoverWidget() { + qDebug() << "hideCurHoverWidget() "; + if(mCurrentHoverWidget){ + qDebug() << mCurrentHoverWidget->objectName(); + mCurrentHoverWidget->hide(); + mCurrentHoverWidget = nullptr; + } +} + +void MainWidget::resizeEvent(QResizeEvent *event) { + mServerSettingWidget->resize(size()); + QWidget::resizeEvent(event); +} + + +void MainWidget::keyPressEvent(QKeyEvent *event) { + //qDebug()<<"MainWidget::keyPressEvent"<text(); + if (event->type() == QEvent::KeyPress) { + BackEnd* g = BackEnd::instance(); + if(g->match(event, "主菜单")){ + if(!mMainMenu->isVisible()){ + hideCurHoverWidget(); + int baseHeight = (int)((double)height() * 0.2); + mMainMenu->setGeometry(0, height() - baseHeight, width(), baseHeight); + mMainMenu->raise(); + mMainMenu->show(); + setCurrentHoverWidget(mMainMenu); + mMainMenu->setFocus(); + } else { + mMainMenu->hide(); + getCurrentBaseWidget()->setFocus(); + } + } + if(g->match(event, "属性菜单")){ + getCurrentBaseWidget()->reserverMenu(); + event->accept(); + return; + } + if(g->match(event, "顶部菜单")){ + if(!mTopMenu->isVisible()){ + hideCurHoverWidget(); + int baseHeight = (int)((double)height() * 0.2); + mTopMenu->setGeometry(0, 0, width(), baseHeight); + mTopMenu->raise(); + mTopMenu->show(); + setCurrentHoverWidget(mTopMenu); + mTopMenu->setFocus(); + } else { + mTopMenu->hide(); + getCurrentBaseWidget()->setFocus(); + } + } + if(g->match(event, "退出")){ + hideCurHoverWidget(); + getCurrentBaseWidget()->setFocus(); + } + } + event->accept(); +} + + + + + +void MainWidget::wheelEvent(QWheelEvent *event) { + event->accept(); +} + diff --git a/module/radio/BackEnd/MainWidget.h b/module/radio/BackEnd/MainWidget.h new file mode 100644 index 0000000..986c73d --- /dev/null +++ b/module/radio/BackEnd/MainWidget.h @@ -0,0 +1,55 @@ +#ifndef MainWidget_H +#define MainWidget_H +#include "../Global.h" +#include "YSGraphic_Core/base/export.h" +#include +#include +#include +#include + +class IntermediateFrequencyWidget; +class SweepFrequencyWidget; +class RadioWidget; +class BaseWidget; +class ShowTime; +class BaseWidgetMenu; +class QVBoxLayout; +class TopMenuBar; +class ServerSettingWidget; +class FileExplorer; +class MainWidget : public QWidget, public YSG::SingletonWidget { +public: + explicit MainWidget(QWidget *parent = nullptr); + QVBoxLayout *mMainLayout; + RadioWidget *mRadioWidget; + SweepFrequencyWidget *mSweepFrequencyWidget; + IntermediateFrequencyWidget *mIntermediateFrequencyWidget; + TopMenuBar* mTopMenuBar; + BaseWidgetMenu *mMainMenu, *mTopMenu; + ServerSettingWidget* mServerSettingWidget; + void showIntermediateFrequencyWidget() const; + void showSweepFrequencyWidget() const; + void showRadioWidget() const; + void showServerSettingWidget(); + [[nodiscard]] BaseWidget* getCurrentBaseWidget() const; + QWidget* currentHoverWidget() {return mCurrentHoverWidget;} + void setCurrentHoverWidget(QWidget* widget = nullptr); + void hideCurHoverWidget(); + + + bool mSelectShotScreenDialogFirst = true, mSelectAudioFileFirst = true; + FileExplorer *mSelectShotScreenDialog, *mSelectAudioFile; + QAudioRecorder *audioRecorder; + QMediaPlayer *mediaPlayer; +protected: + void paintEvent(QPaintEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + void wheelEvent(QWheelEvent *event) override; +private: + QWidget* mCurrentHoverWidget{}; +}; +#endif + + + diff --git a/module/radio/BackEnd/RadioWidget.cpp b/module/radio/BackEnd/RadioWidget.cpp new file mode 100644 index 0000000..11be411 --- /dev/null +++ b/module/radio/BackEnd/RadioWidget.cpp @@ -0,0 +1,428 @@ +#include "RadioWidget.h" +#include +#include +#include +#include "../component/FrequentShower.h" +#include "../component/ProgressBar.h" +#include "../Global.h" +#include "../menu/BaseWidgetMenu.h" +#include "BackEnd.h" +#include "../BackEnd/MainWidget.h" +#include "YSGraphic_Core/DemoGallery/Tool.h" + +static bool use_Performance_shower = false; +static double max = 160; +static YSG::Range frequent_range = {-12000, 12000}; +QWidget* RadioWidget::createSpectrogramPowerPlot() { + class SpectrumPlot : public YSG::Plot { + public: + YSG::FrequentAxis *xAxis{}; + YSG::Axis *yAxis{}; + YSG::MutiSelectRect* msr{}; + YSG::Spectrum *sp{}; + QMenu *mMenu{}; + void init() override { + Plot::init(); + mObjectName = "SpectrumPlot"; + bindRenderThread(mObjectName + "Thread"); + + + xAxis = YSG::FrequentAxis::Builder(this, Qt::Horizontal) + .set_coordRange(frequent_range) + .set_tickLength(-10) + .build(); + + + yAxis = YSG::Axis::Builder(this, Qt::Vertical) + .set_coordRange({max, 0}) + .set_unitText("功率") + .build(); + + sp = YSG::Spectrum::Builder(xAxis, yAxis) + .set_frequentRange(frequent_range) + .set_frequentPointSize(1024) + .build(); + msr = YSG::MutiSelectRect::Builder(xAxis, yAxis).build(); + if(use_Performance_shower) set_usePerformanceShower(true); + } + protected: + void resizeEvent(QResizeEvent* event) override { + xAxis->set_x(0); + xAxis->set_y(height() - 1); + xAxis->set_pixelSize(width()); + yAxis->set_x(0); + yAxis->set_y(0); + yAxis->set_pixelSize(height()); + } + void contextMenuEvent(QContextMenuEvent* event) override { + if(!mMenu) { + auto ws = + bw(cw(sp, -1), "频谱图") + + bw(cw(xAxis), "频率x轴") + + bw(cw(yAxis), "功率y轴") + + bw(cw(msr), "多选框"); + mMenu = createMenu(this, ws); + } + mMenu->exec(event->globalPos()); + } + }; + auto w = new SpectrumPlot; + w->init(); + mSpectrogramLine = w->sp; + mProgressBar1->mSetValue = [this]() { + double middleFrequent = this->mSpectrogramLine->frequentRange().center(); + bool ok; + this->mProgressBar1->mValue = mSpectrogramLine->getPower(middleFrequent, ok, YSG::SRC::Cache); + }; + return w; +} + + +QWidget* RadioWidget::createWaterFallPlot() { + class WaterFallPlot : public YSG::Plot { + public: + YSG::FrequentAxis *xAxis{}; + YSG::TimeAxis *yAxis{}; + YSG::MutiSelectRect *msr{}; + YSG::WaterFall *wf{}; + QMenu *mMenu{}; + void init() override { + Plot::init(); + mObjectName = "WaterFallPlot"; + bindRenderThread(mObjectName + "Thread"); + xAxis = YSG::FrequentAxis::Builder(this, Qt::Horizontal) + .set_tickLength(-10) + .set_subTickLength(-5) + .set_coordRange(frequent_range) + .build(); + yAxis = YSG::TimeAxis::Builder(this, Qt::Vertical) + .set_timePointSize(100) + .build(); + wf = YSG::WaterFall::Builder(xAxis, yAxis) + .set_frequentRange(frequent_range) + .set_frequentPointSize(1024) + .set_powerRange({0, max}) + // .set_timePointSize(100) + .build(); + msr = YSG::MutiSelectRect::Builder(xAxis, yAxis).build(); + if(use_Performance_shower) set_usePerformanceShower(true); + } + protected: + void resizeEvent(QResizeEvent* event) override { + xAxis->set_x(0); + xAxis->set_y(height()); + xAxis->set_pixelSize(width()); + yAxis->set_x(0); + yAxis->set_y(0); + yAxis->set_pixelSize(height()); + } + void contextMenuEvent(QContextMenuEvent* event) override { + if(!mMenu) { + auto ws = + bw(cw(wf, -1), "瀑布图") + + bw(cw(xAxis), "频率轴") + + bw(cw(yAxis), "时间轴") + + bw(cw(msr), "多选框"); + mMenu = createMenu(this, ws); + } + mMenu->exec(event->globalPos()); + } + }; + auto w = new WaterFallPlot; + w->init(); + mWaterFall = w->wf; + return w; +} + + +QWidget* RadioWidget::createAudioSpectrogramPlot() { + class SpectrumPlot : public YSG::Plot { + public: + YSG::FrequentAxis *xAxis{}; + YSG::Axis *yAxis{}; + YSG::MutiSelectRect* msr{}; + YSG::Spectrum *sp{}; + QMenu *mMenu{}; + void init() override { + Plot::init(); + mObjectName = "SpectrumPlot"; + bindRenderThread(mObjectName + "Thread"); + + + xAxis = YSG::FrequentAxis::Builder(this, Qt::Horizontal) + .set_coordRange({-12000 ,12000}) + .set_tickLength(-10) + .set_subTickLength(-5) + .build(); + + + yAxis = YSG::Axis::Builder(this, Qt::Vertical) + .set_coordRange({12000, -12000}) + .set_unitText("功率").build(); + + + sp = YSG::Spectrum::Builder(xAxis, yAxis) + .set_frequentRange({-12000 ,12000}) + .set_frequentPointSize(512) + .build(); + + msr = YSG::MutiSelectRect::Builder(xAxis, yAxis).build(); + + if(use_Performance_shower) set_usePerformanceShower(true); + } + protected: + void resizeEvent(QResizeEvent* event) override { + xAxis->set_x(0); + xAxis->set_y(height() - 1); + xAxis->set_pixelSize(width()); + yAxis->set_x(0); + yAxis->set_y(0); + yAxis->set_pixelSize(height()); + } + + + void contextMenuEvent(QContextMenuEvent* event) override { + if(!mMenu) { + auto ws = + bw(cw(sp, -1), "频谱图") + + bw(cw(xAxis), "频率x轴") + + bw(cw(yAxis), "功率y轴") + + bw(cw(msr), "多选框"); + mMenu = createMenu(this, ws); + } + mMenu->exec(event->globalPos()); + } + }; + auto w = new SpectrumPlot; + w->init(); + mAudioSpectrogramPlot = w->sp; + return w; +} + +QWidget* RadioWidget::createTimePowerPlot() { + class AudioPlot : public YSG::Plot { + public: + YSG::TimeAxis *xAxis{}; + YSG::Axis *yAxis{}; + YSG::AudioFrequent *audio{}; + YSG::MutiSelectRect* msr{}; + QMenu *mMenu{}; + void init() override { + Plot::init(); + mObjectName = "AudioPlot"; + bindRenderThread(mObjectName + "Thread"); + + xAxis = YSG::TimeAxis::Builder(this, Qt::Horizontal) + .set_tickLength(-10) + .set_subTickLength(-5) + .build(); + + yAxis = YSG::Axis::Builder(this, Qt::Vertical) + .set_coordRange({12000, -12000}) + .build(); + + + audio = YSG::AudioFrequent::Builder(xAxis, yAxis) + .build(); + msr = YSG::MutiSelectRect::Builder(xAxis, yAxis).build(); + + + if(use_Performance_shower) set_usePerformanceShower(true); + } + protected: + void resizeEvent(QResizeEvent* event) override { + xAxis->set_x(0); + xAxis->set_y(height() - 1); + xAxis->set_pixelSize(width()); + yAxis->set_x(0); + yAxis->set_y(0); + yAxis->set_pixelSize(height()); + audio->set_timePointSize(xAxis->getPixelPointSize()); + } + void contextMenuEvent(QContextMenuEvent* event) override { + if(!mMenu) { + auto ws = + bw( cw(audio, -1), "音频图") + + bw(cw(yAxis),"功率y轴") + + bw(cw(xAxis), "时间轴") + + bw(cw(msr), "多选框"); + mMenu = createMenu(this, ws); + } + mMenu->exec(event->globalPos()); + } + }; + auto w = new AudioPlot; + w->init(); + mTimePower = w->audio; + return w; +} + + +//mAM, mATU, mVSQL, mNB, mNR, mDNF, mPRE, mATT, mSPL, mFIL1, mAGC_A +RadioWidget::RadioWidget(QWidget *parent) : BaseWidget(parent) { + setObjectName("电台界面"); + mVoiceValue = BackEnd::instance()->YsGetAfGain(); + mRFGainValue = BackEnd::instance()->YsGetRfGain(); + int fontSize = 20; + m1 = createNormal("RF Gain\n" + QString::number(mRFGainValue), fontSize); + m2 = createNormal("FFT SPAN\n100K", fontSize); + m3 = createNormal("频率表\n(12)89.6MHZ", fontSize); + m4 = createNormal("MODEM\nRTTY", fontSize); + m5 = createNormal("FIL1\n20K", fontSize); + m6 = createNormal("MSG1\n", fontSize); + mSelectValueWidget = new FrequentShower(this); + int n = 5; + QVector tickList(n); + double space = 100.0/n; + for(int i = 0; i < n; ++i){ + tickList[i] = i * space; + } + QColor orange(255, 165, 0); + mProgressBar1 = new ProgressBar({ + Tick("S", Qt::black), + {"3", Qt::black}, + {"6", Qt::black}, + {"9", Qt::black}, + {"20", Qt::black}, + {"40", orange}, + {"60", orange}, + {"100", orange}, + {"+160", Qt::red}, + }, this); + + mProgressBar2 = new ProgressBar({ + {"1", Qt::black}, + {"2", Qt::yellow}, + {"3", Qt::red}, + {">5", Qt::red}, + }, this); + mProgressBar1->mTickSpaceW = 2.0f; + auto main = createVBoxLayout({}, this); + + main->addStretch(1); + { // 中心Layout + auto center = createHBoxLayout(); + main->addLayout(center, 7); + auto front = createVBoxLayout(); + center->addLayout(front, 1); + front->addWidget(m1, 3); + front->addStretch(1); + front->addWidget(m2, 3); + center->addSpacing(4); + auto middle = createVBoxLayout(); + center->addLayout(middle, 9); + middle->addStretch(1); + middle->addWidget(mSelectValueWidget, 4); + auto middleH = createHBoxLayout(); + middle->addLayout(middleH, 2); + middleH->addWidget(mProgressBar1, 5); + middleH->addStretch(1); + middleH->addWidget(mProgressBar2, 3); + center->addStretch(4); + auto back1 = createVBoxLayout(); + center->addLayout(back1, 1); + back1->addWidget(m3, 3); + back1->addStretch(1); + back1->addWidget(m4, 3); + center->addSpacing(4); + auto back2 = createVBoxLayout(); + center->addLayout(back2, 1); + back2->addWidget(m5, 3); + back2->addStretch(1); + back2->addWidget(m6, 3); + } + main->addStretch(1); + + + auto aH1 = createHBoxLayout(); + aH1->setSpacing(8); + main->addLayout(aH1, 12); + aH1->addWidget(createSpectrogramPowerPlot(), 12); + aH1->addWidget(createTimePowerPlot(), 4); + main->addSpacing(8); + auto aH2 = createHBoxLayout(); + aH2->setSpacing(8); + main->addLayout(aH2, 12); + aH2->addWidget(createWaterFallPlot(), 12); + aH2->addWidget(createAudioSpectrogramPlot(), 4); + initMenu(); +} + +RadioWidget::~RadioWidget() { +} + +void RadioWidget::initMenu() { + int fontSize = 30; + auto btn1_1 = new MenuButton("模式设置", fontSize, [](){}); + auto btn1_2 = new ValueMenuButton("发射功率:%1 W", fontSize, [&](ValueMenuButton* that, bool add){ + that->setValue(that->mValue + (double)(add?1:-1)); + }, -1); + + + auto btn2_1 = new ValueMenuButton("参考增益:%1", fontSize, [&](ValueMenuButton* that, bool add){ + that->setValue(that->mValue + (double)(add?1:-1)); + }, -1); + + mBaseWidgetMenu->addMenuButtonOnLayout1({btn1_1, btn1_2, {btn2_1},}); + //mBaseWidgetMenu->addMenuButtonOnLayout2( ); + BaseWidgetMenu* sub1 = mBaseWidgetMenu->createSubWidgetMenu(btn1_1); + auto s1_1 = new MenuButton("AM", fontSize, [](){ + + }); + auto s1_2 = new MenuButton("FM", fontSize, [](){ + + }); + auto s1_3 = new MenuButton("SSB", fontSize, [](){ + + }); + auto s1_4 = new MenuButton("CW", fontSize, [](){ + + }); + sub1->addMenuButtonOnLayout1({s1_1, s1_2, s1_3, s1_4}, 1); + + + +} + +void RadioWidget::focusInEvent(QFocusEvent *event) { + QWidget::focusInEvent(event); + mSelectValueWidget->setFocus(); +} + +void RadioWidget::keyPressEvent(QKeyEvent *event) { + if (event->type() == QEvent::KeyPress) { + BackEnd* g = BackEnd::instance(); + auto *keyEvent = dynamic_cast(event); + if(g->match(keyEvent, "切换音量/RF Gain")){ + if(m1->text().startsWith("RF Gain")){ + m1->setText("Voice\n" + QString::number(mVoiceValue)); + } else { + m1->setText("RF Gain\n" + QString::number(mRFGainValue)); + } + } + if(g->match(keyEvent, "特别增加")){ + if(m1->text().startsWith("RF Gain")){ + mRFGainValue++; + BackEnd::instance()->YsSetRfGain(mRFGainValue); + m1->setText("RF Gain\n" + QString::number(mRFGainValue)); + } else { + mVoiceValue++; + BackEnd::instance()->YsSetAfGain(mVoiceValue); + m1->setText("Voice\n" + QString::number(mVoiceValue)); + } + } + if(g->match(keyEvent, "特别减小")){ + if(m1->text().startsWith("RF Gain")){ + mRFGainValue--; + BackEnd::instance()->YsSetRfGain(mRFGainValue); + m1->setText("RF Gain\n" + QString::number(mRFGainValue)); + } else { + mVoiceValue--; + BackEnd::instance()->YsSetAfGain(mVoiceValue); + m1->setText("Voice\n" + QString::number(mVoiceValue)); + } + } + } + BaseWidget::keyPressEvent(event); +} + diff --git a/module/radio/BackEnd/RadioWidget.h b/module/radio/BackEnd/RadioWidget.h new file mode 100644 index 0000000..b50c526 --- /dev/null +++ b/module/radio/BackEnd/RadioWidget.h @@ -0,0 +1,40 @@ +#ifndef RadioWidget_H +#define RadioWidget_H +#include "../BaseWidget.h" + + +class TextButton; +class DoubleTextButton; +class FrequentShower; +class ProgressBar; +class ConsoleWidget; +class ShowTime; + + +class RadioWidget : public BaseWidget { +Q_OBJECT +public: + explicit RadioWidget(QWidget *parent = nullptr); + ~RadioWidget() override; + int mVoiceValue = 0, mRFGainValue = 0; + QPushButton *m1, *m2, *m3, *m4, *m5, *m6; + FrequentShower *mSelectValueWidget; + ProgressBar *mProgressBar1, *mProgressBar2; + void initMenu(); + QWidget* createSpectrogramPowerPlot(); + QWidget* createAudioSpectrogramPlot(); + QWidget* createTimePowerPlot(); + QWidget* createWaterFallPlot(); + YSG::Spectrum *mSpectrogramLine{}; + YSG::Spectrum* mAudioSpectrogramPlot{}; + YSG::AudioFrequent *mTimePower{}; + YSG::WaterFall *mWaterFall{}; +protected: + void focusInEvent(QFocusEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + +}; +#endif + + + diff --git a/module/radio/BackEnd/SweepFrequencyWidget.cpp b/module/radio/BackEnd/SweepFrequencyWidget.cpp new file mode 100644 index 0000000..82ce6bc --- /dev/null +++ b/module/radio/BackEnd/SweepFrequencyWidget.cpp @@ -0,0 +1,162 @@ +#include "SweepFrequencyWidget.h" +#include +#include +#include +#include +#include +#include "../component/FrequentShower.h" +#include "../component/ProgressBar.h" +#include "../component/ConsoleWidget.h" +#include "../component/ShowTime.h" +#include "../Global.h" +#include "../menu/BaseWidgetMenu.h" +#include "YSGraphic_Core/DemoGallery/Tool.h" +QWidget* SweepFrequencyWidget::createSpectrogramPowerPlot() { + class SweepFrequentPlot : public YSG::Plot { + public: + YSG::Axis *xAxis{}; + YSG::Axis *yAxis{}; + YSG::MutiSelectRect *msr{}; + YSG::SweepFrequent* sf{}; + QMenu *mMenu{}; + void init() override { + Plot::init(); + mObjectName = "AxisTestPlot"; + bindRenderThread(mObjectName + "Thread"); + + + xAxis = YSG::Axis::Builder(this, Qt::Horizontal) + .set_coordRange({0, 100}) + .set_tickLength(-10).build(); + + yAxis = YSG::Axis::Builder(this, Qt::Vertical) + .set_coordRange({100, 0}) + .set_tickLength(-10).build(); + + + sf = YSG::SweepFrequent::Builder(xAxis, yAxis) + .set_blockNum(200) + .set_blockFrequentPointSize(20) + .set_frequentRange({0 , 100}) + .build(); + + + msr = YSG::MutiSelectRect::Builder(xAxis, yAxis).build(); + } + protected: + void resizeEvent(QResizeEvent* event) override { + xAxis->set_x(0); + xAxis->set_y(height() - 1); + xAxis->set_pixelSize(width()); + yAxis->set_x(0); + yAxis->set_y(0); + yAxis->set_pixelSize(height()); + } + void contextMenuEvent(QContextMenuEvent* event) override { + if(!mMenu) { + auto ws = + bw(cw(sf, -1), "扫频图") + + bw(cw(xAxis), "x轴") + + bw(cw(yAxis), "y轴") + + bw(cw(msr), "多选框"); + mMenu = createMenu(this, ws); + } + mMenu->exec(event->globalPos()); + } + }; + auto w = new SweepFrequentPlot; + w->init(); + mSweepFrequencyLine = w->sf; + return w; +} + +//mAM, mATU, mVSQL, mNB, mNR, mDNF, mPRE, mATT, mSPL, mFIL1, mAGC_A +SweepFrequencyWidget::SweepFrequencyWidget(QWidget *parent) : BaseWidget(parent) { + setObjectName("扫频界面"); + int fontSize = 20; + m1 = createNormal("RF Gain\n62", fontSize); + m2 = createNormal("FFT SPAN\n100K", fontSize); + m3 = createNormal("频率表\n(12)89.6MHZ", fontSize); + m4 = createNormal("MODEM\nRTTY", fontSize); + mSelectValueWidget = new FrequentShower(this); + mProgressBar1 = new ProgressBar({ + {"S", Qt::black}, + {"3", Qt::black}, + {"5", Qt::black}, + {"7", Qt::black}, + {"9", Qt::black}, + {"+20", Qt::yellow}, + {"+40", Qt::yellow}, + {"+60", Qt::red}, + }, this); + mProgressBar2 = new ProgressBar({ + {"1", Qt::black}, + {"2", Qt::yellow}, + {"3", Qt::red}, + {">5", Qt::red}, + }, this); + + auto main = createVBoxLayout({}, this); + main->addStretch(1); + { // 中心Layout + auto center = createHBoxLayout(); + main->addLayout(center, 7); + auto front = createVBoxLayout(); + center->addLayout(front, 1); + front->addWidget(m1, 3); + front->addStretch(1); + front->addWidget(m2, 3); + center->addSpacing(4); + auto middle = createVBoxLayout(); + center->addLayout(middle, 9); + middle->addStretch(1); + middle->addWidget(mSelectValueWidget, 4); + auto middleH = createHBoxLayout(); + middle->addLayout(middleH, 2); + middleH->addWidget(mProgressBar1, 5); + middleH->addStretch(1); + middleH->addWidget(mProgressBar2, 3); + center->addStretch(5); + center->addSpacing(4); + auto back1 = createVBoxLayout(); + center->addLayout(back1, 1); + back1->addWidget(m3, 3); + back1->addStretch(1); + back1->addWidget(m4, 3); + } + main->addStretch(1); + main->addSpacing(8); + //main->addWidget(new TestWidget, 24); + main->addWidget(createSpectrogramPowerPlot(), 24); + initMenu(); +} + +SweepFrequencyWidget::~SweepFrequencyWidget() { +} + +void SweepFrequencyWidget::focusInEvent(QFocusEvent *event) { + QWidget::focusInEvent(event); + mSelectValueWidget->setFocus(); +} + +void SweepFrequencyWidget::initMenu() { + int fontSize = 30; + auto startFreq = new ValueMenuButton("起始频率:%1 Hz", fontSize, [&](ValueMenuButton* that, bool add){ + that->setValue(that->mValue + (double)(add ? 1 : -1)); + }, -1); + startFreq->setValue(mSweepFrequencyLine->frequentRange().lower); + auto endFreq = new ValueMenuButton("终止频率:%1 Hz", fontSize, [&](ValueMenuButton* that, bool add){ + that->setValue(that->mValue + (double)(add ? 1 : -1)); + }, -1); + endFreq->setValue(mSweepFrequencyLine->frequentRange().upper); + auto btn3 = new MenuButton("设置频率", fontSize, [&, startFreq, endFreq](){ + mSweepFrequencyLine->set_frequentRange({startFreq->mValue, endFreq->mValue}); + }); + mBaseWidgetMenu->addMenuButtonOnLayout1({startFreq, endFreq, btn3}, 2); +} + + + + + + diff --git a/module/radio/BackEnd/SweepFrequencyWidget.h b/module/radio/BackEnd/SweepFrequencyWidget.h new file mode 100644 index 0000000..d88841b --- /dev/null +++ b/module/radio/BackEnd/SweepFrequencyWidget.h @@ -0,0 +1,33 @@ +#ifndef SweepFrequencyWidget_H +#define SweepFrequencyWidget_H +#include "../BaseWidget.h" +class TextButton; +class DoubleTextButton; +class FrequentShower; +class ProgressBar; +class ConsoleWidget; +class ShowTime; +namespace YS{ + class SpectrogramPowerPlot; + class TimePowerPlot; + class SweepFrequencyLine; +} + +class SweepFrequencyWidget : public BaseWidget { +Q_OBJECT +public: + explicit SweepFrequencyWidget(QWidget *parent = nullptr); + ~SweepFrequencyWidget() override; + QPushButton *m1, *m2, *m3, *m4; + FrequentShower *mSelectValueWidget; + ProgressBar *mProgressBar1, *mProgressBar2; + void initMenu(); + YSG::SweepFrequent *mSweepFrequencyLine{}; + QWidget* createSpectrogramPowerPlot(); +protected: + void focusInEvent(QFocusEvent *event) override; +}; +#endif + + + diff --git a/module/radio/BaseWidget.cpp b/module/radio/BaseWidget.cpp new file mode 100644 index 0000000..4579f4f --- /dev/null +++ b/module/radio/BaseWidget.cpp @@ -0,0 +1,54 @@ +#include "BaseWidget.h" +#include "menu/BaseWidgetMenu.h" +#include "BackEnd/MainWidget.h" +#include "Global.h" + + + +BaseWidget::BaseWidget(QWidget *parent) : QWidget(parent) { +// setAttribute(Qt::WA_OpaquePaintEvent); + mBaseWidgetMenu = new BaseWidgetMenu(this); + mBaseWidgetMenu->setObjectName("属性菜单"); + hide(); +} + + +void BaseWidget::resizeEvent(QResizeEvent *event) { + int baseHeight = (int)((double)height() * 0.2); + mBaseWidgetMenu->setGeometry(0, height() - baseHeight, width(), baseHeight); + QWidget::resizeEvent(event); +} + +void BaseWidget::reserverMenu() { + if(!mBaseWidgetMenu->isVisible()){ + QWidget* curWidget = MainWidget::instance()->currentHoverWidget(); + if(curWidget) curWidget->hide(); + mBaseWidgetMenu->raise(); + mBaseWidgetMenu->show(); + curWidget = mBaseWidgetMenu; + mBaseWidgetMenu->setFocus(); + } else { + mBaseWidgetMenu->hide(); + setFocus(); + } +} + +void BaseWidget::keyPressEvent(QKeyEvent *event) { + if (event->type() == QEvent::KeyPress) { + Global *g = Global::instance(); + auto *keyEvent = dynamic_cast(event); + //qDebug() << keyEvent; +// if(g->match(keyEvent, "属性菜单")){ +// reserverMenu(); +// event->accept(); +// return; +// } + + } + event->ignore(); + +} + + + + diff --git a/module/radio/BaseWidget.h b/module/radio/BaseWidget.h new file mode 100644 index 0000000..f1b4a57 --- /dev/null +++ b/module/radio/BaseWidget.h @@ -0,0 +1,23 @@ +#ifndef BaseWidget_H +#define BaseWidget_H +#include "Global.h" +#include "YSGraphic_Core/export.h" + +class BaseWidgetMenu; +class QHBoxLayout; +class MainWidget; +class DoubleTextButton; +class BaseWidget : public QWidget { +public: + explicit BaseWidget(QWidget *parent = nullptr); + BaseWidgetMenu *mBaseWidgetMenu; + void reserverMenu(); +protected: +// void paintEvent(QPaintEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; +}; +#endif + + + diff --git a/module/radio/FileDialog/CustomFileDelegate.cpp b/module/radio/FileDialog/CustomFileDelegate.cpp new file mode 100644 index 0000000..a0b12e8 --- /dev/null +++ b/module/radio/FileDialog/CustomFileDelegate.cpp @@ -0,0 +1,48 @@ +#include "CustomFileDelegate.h" + +#include "FileExplorer.h" +CustomFileDelegate::CustomFileDelegate(FileExplorer* fileExplorer, QObject* parent): QStyledItemDelegate(parent) { + this->fileExplorer = fileExplorer; +} +void CustomFileDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { + // 获取数据 + QFileSystemModel *model = qobject_cast(const_cast(index.model())); + if (!model) { + QStyledItemDelegate::paint(painter, option, index); + return; + } + + QString fileName = model->fileName(index); // 文件/文件夹名称 + QFileInfo fileInfo = model->fileInfo(index); // 文件/文件夹信息 + QIcon fileIcon = model->fileIcon(index); // 文件/文件夹图标 + + // 设置选中和未选中背景颜色 + QColor backgroundColor = fileInfo.isDir() ? QColor(220, 240, 255) : QColor(255, 255, 220); // 文件夹和文件的不同背景色 + if (option.state & QStyle::State_Selected) { + backgroundColor = QColor(0, 120, 215); // 选中的背景色 + } + + // 绘制背景 + painter->fillRect(option.rect, backgroundColor); + + // 设置文本颜色 + QColor textColor = (option.state & QStyle::State_Selected) ? Qt::white : Qt::black; + + // 绘制图标 + QRect iconRect = option.rect; + iconRect.setWidth(fileExplorer->height); // 图标宽度 + fileIcon.paint(painter, iconRect, Qt::AlignVCenter | Qt::AlignLeft); + + // 绘制文件名 + QRect textRect = option.rect; + textRect.setLeft(iconRect.right() + 5); // 图标右侧开始绘制文本 + painter->setPen(textColor); + painter->drawText(textRect, Qt::AlignVCenter | Qt::AlignLeft, fileName); + + // 调用父类实现绘制焦点等其他内容 + //QStyledItemDelegate::paint(painter, option, Windex); +} +QSize CustomFileDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { + QSize defaultSize = QStyledItemDelegate::sizeHint(option, index); + return QSize(defaultSize.width(), fileExplorer->height); // 自定义行高 +} diff --git a/module/radio/FileDialog/CustomFileDelegate.h b/module/radio/FileDialog/CustomFileDelegate.h new file mode 100644 index 0000000..9b9b967 --- /dev/null +++ b/module/radio/FileDialog/CustomFileDelegate.h @@ -0,0 +1,21 @@ +#ifndef CUSTOMFILEDELEGATE_H +#define CUSTOMFILEDELEGATE_H + +#include +#include +#include +#include + +class FileExplorer; +class CustomFileDelegate : public QStyledItemDelegate { + Q_OBJECT +public: + explicit CustomFileDelegate(FileExplorer *fileExplorer, QObject *parent = nullptr); + FileExplorer *fileExplorer{}; + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; +}; + + +#endif diff --git a/module/radio/FileDialog/FileExplorer.cpp b/module/radio/FileDialog/FileExplorer.cpp new file mode 100644 index 0000000..ee7a995 --- /dev/null +++ b/module/radio/FileDialog/FileExplorer.cpp @@ -0,0 +1,41 @@ +#include "FileExplorer.h" +#include "CustomFileDelegate.h" + + +FileExplorer::FileExplorer() { + model = new QFileSystemModel(this); + resize(1000, 800); + treeView = new QTreeView(this); + treeView->setModel(model); + it = new CustomFileDelegate(this, treeView); + treeView->setItemDelegate(it); + treeView->setHeaderHidden(false); + treeView->setColumnWidth(0, 250); + treeView->setAnimated(true); + treeView->setSortingEnabled(true); + treeView->setSelectionMode(QAbstractItemView::SingleSelection); + layout = new QVBoxLayout(this); + showRootDir = new QLineEdit; + showFocusFile = new QLabel; + layout->addWidget(showRootDir); + layout->addWidget(treeView); + auto bottom = new QHBoxLayout(); + confirmButton = new QPushButton("确定"); + cancelButton = new QPushButton("取消"); + confirmButton->setFixedHeight(height); + cancelButton->setFixedHeight(height); + + bottom->addWidget(showFocusFile); + bottom->addWidget(confirmButton); + bottom->addWidget(cancelButton); + layout->addLayout(bottom); + changeRoot("D:/"); + + connect(showRootDir, &QLineEdit::returnPressed, [this](){ + changeRoot(showRootDir->text()); + }); + connect(treeView, &QTreeView::clicked, [this](const QModelIndex &index) { + focus = model->fileInfo(index); + showFocusFile->setText(focus.fileName()); + }); +} \ No newline at end of file diff --git a/module/radio/FileDialog/FileExplorer.h b/module/radio/FileDialog/FileExplorer.h new file mode 100644 index 0000000..7fc9a52 --- /dev/null +++ b/module/radio/FileDialog/FileExplorer.h @@ -0,0 +1,133 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "CustomFileDelegate.h" // 包含自定义代理类 + + + + + +// class CustomStyle : public QProxyStyle { +// public: +// explicit CustomStyle(QStyle *baseStyle = nullptr) : QProxyStyle(baseStyle) {} +// +// void drawPrimitive(QStyle::PrimitiveElement element, +// const QStyleOption *option, +// QPainter *painter, +// const QWidget *widget = nullptr) const override { +// if (element == QStyle::PE_IndicatorBranch) { +// // 自定义绘制箭头 +// QRect rect = option->rect; +// QPoint center = rect.center(); +// if (option->state & QStyle::State_Open) { +// // 绘制展开的箭头(向下) +// QPoint points[3] = { +// QPoint(center.x() - 5, center.y() - 2), +// QPoint(center.x() + 5, center.y() - 2), +// QPoint(center.x(), center.y() + 5) +// }; +// painter->setBrush(Qt::black); +// painter->drawPolygon(points, 3); +// } else { +// // 绘制收起的箭头(向右) +// QPoint points[3] = { +// QPoint(center.x() - 2, center.y() - 5), +// QPoint(center.x() - 2, center.y() + 5), +// QPoint(center.x() + 5, center.y()) +// }; +// painter->setBrush(Qt::black); +// painter->drawPolygon(points, 3); +// } +// } else { +// // 调用默认绘制逻辑 +// QProxyStyle::drawPrimitive(element, option, painter, widget); +// } +// } +// }; +// + + +class CustomFileDelegate; +class FileExplorer : public QWidget { + Q_OBJECT +public: + QTreeView *treeView; + QFileSystemModel *model; + QVBoxLayout *layout; + QLineEdit* showRootDir; + QFileInfo focus; + QLabel *showFocusFile; + QPushButton *confirmButton, *cancelButton; + int height = 60; + CustomFileDelegate *it; + void showCenter() { + QScreen *screen = QGuiApplication::primaryScreen(); + QRect screenRect = screen->availableGeometry(); + QRect windowRect = frameGeometry(); + int x = (screenRect.width() - windowRect.width()) / 2; + int y = (screenRect.height() - windowRect.height()) / 2; + move(x, y); + show(); + } + void resizeEvent(QResizeEvent* event) override { + + } +protected: + void paintEvent(QPaintEvent* event) override { + QPainter painter(this); + painter.fillRect(rect(), Qt::white); + painter.end(); + } +public: + void changeRoot(QString dir_path) { + dir_path.replace("\\", "/"); + QFileInfo fileInfo(dir_path); // 用 QFileInfo 检测路径 + if (fileInfo.isDir()) { + //qDebug() << "dir " << dir_path; + } else if (fileInfo.isFile()) { + //qDebug() << "file " << dir_path; + focus = fileInfo; + showFocusFile->setText(focus.absolutePath()); + dir_path = fileInfo.dir().absolutePath(); + } else { + //qDebug() << "error " << dir_path; + showRootDir->setText(model->rootPath()); + return; + } + if (!dir_path.endsWith("/")) { + dir_path.append("/"); + } + showRootDir->setText(dir_path); + model->setRootPath(dir_path); + treeView->setRootIndex(model->index(dir_path)); + + model->setHeaderData(0,Qt::Horizontal,"文件名称"); + model->setHeaderData(1,Qt::Horizontal,"文件大小"); + + treeView->setColumnWidth(0, 500); + } + + FileExplorer(); +}; + + + diff --git a/module/radio/Global.cpp b/module/radio/Global.cpp new file mode 100644 index 0000000..eecd462 --- /dev/null +++ b/module/radio/Global.cpp @@ -0,0 +1,157 @@ +#include "Global.h" +#include "BackEnd/MainWidget.h" +#include "YSGraphic_Core/base/export.h" +#include "menu/BaseWidgetMenu.h" +#include + +QVBoxLayout* createVBoxLayout(const QVector& children, QWidget *parent){ + auto ret = new QVBoxLayout(parent); + ret->setMargin(0); + ret->setSpacing(0); +// ret->setSizeConstraint(QLayout::SizeConstraint::SetFixedSize); + for(auto child : children){ + ret->addWidget(child, 1); + } + return ret; +} + +QHBoxLayout* createHBoxLayout(const QVector& children, QWidget *parent){ + auto ret = new QHBoxLayout(parent); + ret->setMargin(0); + ret->setSpacing(0); +// ret->setSizeConstraint(QLayout::SizeConstraint::SetFixedSize); + for(auto child : children){ + ret->addWidget(child, 1); + } + return ret; +} + +QRect getMaxRect(const QRect& rect, double WHRate){ + double w = rect.width(), h = rect.height(); + QRect ret; + if(w/h > WHRate) { + double shouldW = h * WHRate; + double x = (w - shouldW)/2; + ret = QRect((int)x, 0, (int)shouldW, (int)h); + } else { + double shouldH = w / WHRate; + double y = (h - shouldH)/2; + ret = QRect(0, (int)y, (int)w, (int)shouldH); + } + return ret; +} + + +int calculateOptimalFontSize(const QVector& textList, const QSize& spaceSize, const QFont& font) { + int fontSize = 1, textWidth, textHeight; + do { + textWidth = -1; + textHeight = 0; + QFontMetrics fontMetrics(QFont(font.family(), fontSize)); + for(const QString& text : textList){ + textWidth = std::max(textWidth, fontMetrics.horizontalAdvance(text)); + textHeight += fontMetrics.height(); + } + fontSize++; + } while (textWidth < spaceSize.width() && textHeight < spaceSize.height()); + return fontSize; +} + +int calculateOptimalFontSize(const QString& text, const QSize& spaceSize, const QFont& font) { + int fontSize = 1, textWidth, textHeight; + do { + QFontMetrics fontMetrics(QFont(font.family(), fontSize)); + textWidth = fontMetrics.horizontalAdvance(text); + textHeight = fontMetrics.height(); + fontSize++; + } while (textWidth < spaceSize.width() && textHeight < spaceSize.height()); + return fontSize; +} + +Global::Global() { + +} + +int Global::adaptHeight(int fullScreenHeight) { + auto m = MainWidget::instance(); + return (int)(double(m->height() * fullScreenHeight)/double(QGuiApplication::primaryScreen()->size().height())); +} + +int Global::adaptWidth(int fullScreenWidth) { + auto m = MainWidget::instance(); + return (int)(double(m->width() * fullScreenWidth)/double(QGuiApplication::primaryScreen()->size().width())); +} + + + +QPushButton *createButton(const QString& text, int fontSize, const std::function& mFunc) { + auto button = new QPushButton(text); + button->setDisabled(true); + button->setFocusPolicy(Qt::NoFocus); + button->setFlat(true); + button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + button->setCheckable(true); + button->setChecked(false); + QFont font; + font.setPixelSize(fontSize); + button->setFont(font); + if(mFunc) QObject::connect(button, &QPushButton::clicked, mFunc); + return button; +} + +QPushButton *createClickButton(const QString &text, int fontSize, const std::function &mFunc, + YSG::RollObject *rollObject) { + auto button = new QPushButton; + initClickButton(button, text, fontSize, mFunc, rollObject); + return button; +} + +void initClickButton(QPushButton* button, const QString &text, int fontSize, const std::function &mFunc, + YSG::RollObject *rollObject){ + button->setText(text); + button->setFocusPolicy(Qt::NoFocus); + button->setFlat(true); + button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + button->setCheckable(true); + button->setChecked(false); + QFont font; + font.setPixelSize(fontSize); + button->setFont(font); + if(mFunc) QObject::connect(button, &QPushButton::clicked, [button, rollObject, mFunc](){ + rollObject->setCur(button); + mFunc(); + }); +} + + + +QPushButton* createNormal(const QString& text, int fontSize, const std::function& mFunc) { + auto button = new QPushButton(text); + button->setDisabled(true); + + + button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + button->setFocusPolicy(Qt::NoFocus); + + //button->setDefault(true); + QFont font; + font.setPixelSize(fontSize); + button->setFont(font); + if(mFunc) QObject::connect(button, &QPushButton::clicked, mFunc); + return button; +} + + +// int cellWidth = width() / 15; +// int cellHeight = height() / 32; +// // 绘制水平线条 +// for (int row = 0; row < 33; ++row) { +// int y = row * cellHeight; +// painter.drawLine(QPoint(0, y), QPoint(width(), y)); +// } +// // 绘制垂直线条 +// for (int col = 0; col < 17; ++col) { +// int x = col * cellWidth; +// painter.drawLine(QPoint(x, 0), QPoint(x, height())); +// } + diff --git a/module/radio/Global.h b/module/radio/Global.h new file mode 100644 index 0000000..5f70609 --- /dev/null +++ b/module/radio/Global.h @@ -0,0 +1,104 @@ +#ifndef Global_H +#define Global_H +#include "BackEnd/BackEnd.h" +#include "YSGraphic_Core/GlobalTypes.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "psc_global_include/Singleton.hpp" + +// template +// class Singleton { +// public: +// static Derived* instance() { +// Derived* temp = instance_.load(std::memory_order_acquire); +// if (temp == nullptr) { +// std::lock_guard lock(mutex_); +// temp = instance_.load(std::memory_order_relaxed); +// if (temp == nullptr) { +// temp = new Derived; +// instance_.store(temp, std::memory_order_release); +// } +// } +// return temp; +// } +// Singleton(const Singleton&) = delete; +// Singleton& operator=(const Singleton&) = delete; +// protected: +// Singleton() = default; +// ~Singleton() = default; +// private: +// static std::atomic instance_; +// static std::mutex mutex_; +// }; +// template +// std::atomic Singleton::instance_(nullptr); +// template +// std::mutex Singleton::mutex_; + +//template +//class Singleton { +//public: +// static T *instance() { +// if(!mInstance) { +// mInstance = new T(); +// } +// return mInstance; +// } +// virtual ~Singleton() = default; +// Singleton(T &&) = delete; +// Singleton(const T &) = delete; +// void operator=(const T &) = delete; +//protected: +// Singleton() = default; +// static T* mInstance; +//}; +//template T* Singleton::mInstance = nullptr; + + + + + + +class Global : public Psc::Singleton { +public: + explicit Global(); + int adaptHeight(int fullScreenHeight); + int adaptWidth(int fullScreenWidth); +}; + + + + +QVBoxLayout* createVBoxLayout(const QVector& children = {}, QWidget *parent = nullptr); +QHBoxLayout* createHBoxLayout(const QVector& children = {}, QWidget *parent = nullptr); +QRect getMaxRect(const QRect& rect, double WHRate); +int calculateOptimalFontSize(const QString& text, const QSize& spaceSize, const QFont& font); +int calculateOptimalFontSize(const QVector& textList, const QSize& spaceSize, const QFont& font); +QPushButton* createButton(const QString& text, int fontSize, const std::function& mFunc = nullptr); + +namespace YSG{ + template + class RollObject; +} + +class BaseWidgetMenu; + +void initClickButton(QPushButton* button, const QString &text, int fontSize, const std::function &mFunc, YSG::RollObject*); +QPushButton *createClickButton(const QString &text, int fontSize, const std::function &mFunc, YSG::RollObject*); + + + +QPushButton* createNormal(const QString& text, int fontSize, const std::function& mFunc = nullptr); + +#endif \ No newline at end of file diff --git a/module/radio/MainWidget.rar b/module/radio/MainWidget.rar new file mode 100644 index 0000000..244ccc6 Binary files /dev/null and b/module/radio/MainWidget.rar differ diff --git a/module/radio/Toolbox_private/CircularLinkedList.hpp b/module/radio/Toolbox_private/CircularLinkedList.hpp new file mode 100644 index 0000000..359aa3d --- /dev/null +++ b/module/radio/Toolbox_private/CircularLinkedList.hpp @@ -0,0 +1,97 @@ +#ifndef Toolbox_CircularLinkedList_H +#define Toolbox_CircularLinkedList_H + +namespace Toolbox { + template + struct CircularLinkedListNode { + CircularLinkedListNode *prev = nullptr, *next = nullptr; + T data; + }; + template + class CircularLinkedList { + public: + CircularLinkedListNode *mHead = nullptr; + CircularLinkedListNode *mCur = nullptr; + void init(const QVector &dataList) { + mHead = new CircularLinkedListNode(); + mHead->data = dataList.first(); + CircularLinkedListNode *prev = mHead; + int n = dataList.size(); + for (int i = 1; i < n - 1; i++) { + auto node = new CircularLinkedListNode(); + node->data = dataList[i]; + node->prev = prev; + prev->next = node; + prev = node; + } + auto tail = new CircularLinkedListNode(); + tail->data = dataList.last(); + tail->prev = prev; + prev->next = tail; + tail->next = mHead; + mHead->prev = tail; + mCur = mHead; + } + CircularLinkedListNode *move(int step = 1) { + if (step == 0) return nullptr; + return step > 0 ? next(step) : prev(-step); + } + CircularLinkedListNode *next(int step = 1) { + if (step <= 0) return nullptr; + for (int i = 0; i < step; i++) { + mCur = mCur->next; + } + return mCur; + } + CircularLinkedListNode *prev(int step = 1) { + if (step <= 0) return nullptr; + for (int i = 0; i < step; i++) { + mCur = mCur->prev; + } + return mCur; + } + void insertNext(const T &t, CircularLinkedListNode *that = nullptr) { + if (that == nullptr) that = mCur; + auto node = new CircularLinkedListNode(); + node->data = t; + node->next = that->next; + node->prev = that; + that->next = node; + } + void insertPrev(const T &t, CircularLinkedListNode *that = nullptr) { + if (that == nullptr) that = mCur; + auto node = new CircularLinkedListNode(); + node->data = t; + node->prev = that->prev; + node->next = that; + that->prev = node; + } + QVector *> toVector() { + if (mHead == nullptr) return {}; + QVector *> ret; + CircularLinkedListNode *cur = mHead; + do { + ret.push_back(cur); + cur = cur->next; + } while (cur != mHead); + return ret; + } + void clear() { + if (mHead == nullptr) return; + CircularLinkedListNode *cur = mHead; + do { + CircularLinkedListNode *temp = cur; + cur = cur->next; + delete temp; + } while (cur != mHead); + mHead = nullptr; + } + ~CircularLinkedList() { + clear(); + } + }; +} +#endif + + + diff --git a/module/radio/Toolbox_private/Node.hpp b/module/radio/Toolbox_private/Node.hpp new file mode 100644 index 0000000..95fd041 --- /dev/null +++ b/module/radio/Toolbox_private/Node.hpp @@ -0,0 +1,97 @@ +#ifndef Toolbox_Node_H +#define Toolbox_Node_H +#include +#include +namespace Toolbox { + template + class Node { + public: + explicit Node() = default; + int index() { + if (!father) return -1; + return father->sons.indexOf(static_cast(this)); + } + bool root() { return !father; } + bool leaf() { return sons.empty(); } + bool first() { + if (!father) return false; + return this == father->sons.first(); + } + bool last() { + if (!father) return false; + return this == father->sons.last(); + } + That *previous() { + if (!father) return nullptr; + int i = father->sons.indexOf(static_cast(this)) - 1; + if (i < 0) return nullptr; + return father->sons[i]; + } + That *next() { + if (!father) return nullptr; + int i = father->sons.indexOf(static_cast(this)) + 1; + if (i > father->sons.mBufferSize()) return nullptr; + return father->sons[i]; + } + That *lastChild() { + if (sons.empty()) return nullptr; + return sons.last(); + } + That *firstChild() { + if (sons.empty()) return nullptr; + return sons.first(); + } + That *rootNode() { + That *ret = static_cast(this); + while (ret->father != nullptr) { + ret = ret->father; + } + return ret; + } + int deep() { + That *ret = static_cast(this); + while (ret->father != nullptr) { + ret = ret->father; + ret++; + } + return ret; + } + //遍历值 + QVector deepTraversed() { + std::vector ret; + ret.append(static_cast(this)); + for (auto &child: sons) { + ret.append(child->deepTraversed()); + } + return ret; + } + QVector sequenceTraversed() { + QVector ret; + QQueue que; + That *that = static_cast(this); + que.enqueue(that); + while (!que.empty()) { + That *cur = que.dequeue(); + int n = cur->sons.mBufferSize(); + ret.append(cur); + for (int i = 0; i < n; ++i) { + que.enqueue(cur->sons[i]); + } + } + return ret; + } + QVector descendants() { + QVector &&ret = sequenceTraversed(); + ret.pop_front(); + return ret; + } + That *father = nullptr; + QVector sons; + }; + template + class NodeManager { + public: + QVector roots; + }; +} +#endif \ No newline at end of file diff --git a/module/radio/Toolbox_private/RollObject.h b/module/radio/Toolbox_private/RollObject.h new file mode 100644 index 0000000..be44abf --- /dev/null +++ b/module/radio/Toolbox_private/RollObject.h @@ -0,0 +1,69 @@ +#ifndef Toolbox_RollWidget_H +#define Toolbox_RollWidget_H +#include +#include +namespace Toolbox { + template + class RollObject : QObject { + public: + explicit RollObject(QObject *parent = nullptr) : QObject(parent) {} + explicit RollObject(QVector widgets, std::function enterFunc, + std::function leaveFunc, QObject *parent) : + mWidgets(std::move(widgets)), mEnterFunc(enterFunc), mLeaveFunc(leaveFunc), QObject(parent) { + if (mEnterFunc) mEnterFunc(mWidgets[mIndex]); + } + int mIndex = 0; + QVector mWidgets; + std::function mEnterFunc; + std::function mLeaveFunc; + T *cur() { + if (mWidgets.empty()) return nullptr; + return mWidgets[mIndex]; + } + void setCur(T *cur) { + if (mWidgets.empty()) return; + int index = mWidgets.indexOf(cur); + if (mLeaveFunc) mLeaveFunc(mWidgets[mIndex]); + mIndex = index; + if (mEnterFunc) mEnterFunc(mWidgets[mIndex]); + mWidgets[mIndex]->update(); + } + void rollRight() { + if (mWidgets.empty()) return; + if (mLeaveFunc) mLeaveFunc(mWidgets[mIndex]); + mWidgets[mIndex]->update(); + if (mWidgets.last() != mWidgets[mIndex]) { + mIndex++; + } else { + mIndex = 0; + } + if (mEnterFunc) mEnterFunc(mWidgets[mIndex]); + mWidgets[mIndex]->update(); + } + void rollLeft() { + if (mWidgets.empty()) return; + if (mLeaveFunc) mLeaveFunc(mWidgets[mIndex]); + mWidgets[mIndex]->update(); + if (mWidgets.first() != mWidgets[mIndex]) { + mIndex--; + } else { + mIndex = mWidgets.size() - 1; + } + if (mEnterFunc) mEnterFunc(mWidgets[mIndex]); + mWidgets[mIndex]->update(); + } + QHBoxLayout *hBoxLayout(int space) { + auto ret = new QHBoxLayout; + ret->setMargin(0); + ret->setSpacing(space); + for (auto widget: mWidgets) { + ret->addWidget(widget, 1); + } + return ret; + } + }; +} +#endif + + + diff --git a/module/radio/Toolbox_private/Singleton.hpp b/module/radio/Toolbox_private/Singleton.hpp new file mode 100644 index 0000000..ab913fa --- /dev/null +++ b/module/radio/Toolbox_private/Singleton.hpp @@ -0,0 +1,34 @@ +#ifndef Toolbox_Singleton_H +#define Toolbox_Singleton_H +#include +namespace Toolbox { + template + class Singleton { + public: + static Derived *instance() { + Derived *temp = instance_.load(std::memory_order_acquire); + if (temp == nullptr) { + std::lock_guard lock(mutex_); + temp = instance_.load(std::memory_order_relaxed); + if (temp == nullptr) { + temp = new Derived; + instance_.store(temp, std::memory_order_release); + } + } + return temp; + } + Singleton(const Singleton &) = delete; + Singleton &operator=(const Singleton &) = delete; + protected: + Singleton() = default; + ~Singleton() = default; + private: + static std::atomic instance_; + static std::mutex mutex_; + }; + template + std::atomic Singleton::instance_(nullptr); + template + std::mutex Singleton::mutex_; +} +#endif \ No newline at end of file diff --git a/module/radio/Toolbox_private/SingletonWidget.hpp b/module/radio/Toolbox_private/SingletonWidget.hpp new file mode 100644 index 0000000..20cd969 --- /dev/null +++ b/module/radio/Toolbox_private/SingletonWidget.hpp @@ -0,0 +1,29 @@ +#ifndef Toolbox_SingletonWidget_H +#define Toolbox_SingletonWidget_H +#include +namespace Toolbox { + template + class SingletonWidget { + public: + static T *instance() { + if (!mInstance) { + qInfo() << "error SingletonWidget 未创建" << mInstance; + } + return mInstance; + } + SingletonWidget() { + if (mInstance) { + qInfo() << "error SingletonWidget 重复创建" << mInstance; + } + mInstance = static_cast(this); + } + virtual ~SingletonWidget() {} + SingletonWidget(T &&) = delete; + SingletonWidget(const T &) = delete; + void operator=(const T &) = delete; + protected: + static T *mInstance; + }; + template T *SingletonWidget::mInstance = nullptr; +} +#endif diff --git a/module/radio/Toolbox_private/SpinLock.cpp b/module/radio/Toolbox_private/SpinLock.cpp new file mode 100644 index 0000000..2280382 --- /dev/null +++ b/module/radio/Toolbox_private/SpinLock.cpp @@ -0,0 +1,32 @@ +#include +#include "SpinLock.h" +namespace Toolbox { + void SpinLock::lock() { + while (flag.test_and_set(std::memory_order_acquire)) {} + } + bool SpinLock::tryLock() { + return !flag.test_and_set(std::memory_order_acquire); + } + bool SpinLock::tryLock(int durationMillis) { + if (durationMillis == 0) { + return tryLock(); + } + auto duration = std::chrono::milliseconds(durationMillis); + auto start = std::chrono::steady_clock::now(); + while (std::chrono::steady_clock::now() - start < duration) { + if (tryLock()) { + return true; + } + } + return false; + } + void SpinLock::unlock() { + flag.clear(std::memory_order_release); + } + SpinLockGuard::~SpinLockGuard() { + if (mLock) mLock->unlock(); + } + SpinLockGuard::SpinLockGuard(SpinLock *lock) : mLock(lock) { + if (mLock) mLock->lock(); + } +} diff --git a/module/radio/Toolbox_private/SpinLock.h b/module/radio/Toolbox_private/SpinLock.h new file mode 100644 index 0000000..ac80eb3 --- /dev/null +++ b/module/radio/Toolbox_private/SpinLock.h @@ -0,0 +1,22 @@ +#ifndef Toolbox_SpinLock_H +#define Toolbox_SpinLock_H +#include +namespace Toolbox { + class SpinLock { + public: + void lock(); + bool tryLock(); + bool tryLock(int durationMillis); + void unlock(); + private: + std::atomic_flag flag = ATOMIC_FLAG_INIT; + }; + class SpinLockGuard { + public: + explicit SpinLockGuard(SpinLock *lock); + ~SpinLockGuard(); + private: + SpinLock *mLock; + }; +} +#endif \ No newline at end of file diff --git a/module/radio/Toolbox_private/export.h b/module/radio/Toolbox_private/export.h new file mode 100644 index 0000000..119f9d2 --- /dev/null +++ b/module/radio/Toolbox_private/export.h @@ -0,0 +1,8 @@ +#include "Node.hpp" +#include "CircularLinkedList.hpp" +#include "SpinLock.h" +#include "Singleton.hpp" +#include "RollObject.h" +#include "SingletonWidget.hpp" +#include "view/FileFolderBar.h" +#include "pinyin/VirtualKeyBoard.h" \ No newline at end of file diff --git a/module/radio/Toolbox_private/pinyin.rar b/module/radio/Toolbox_private/pinyin.rar new file mode 100644 index 0000000..d4e6848 Binary files /dev/null and b/module/radio/Toolbox_private/pinyin.rar differ diff --git a/module/radio/Toolbox_private/view/FileFolderBar.cpp b/module/radio/Toolbox_private/view/FileFolderBar.cpp new file mode 100644 index 0000000..478fad6 --- /dev/null +++ b/module/radio/Toolbox_private/view/FileFolderBar.cpp @@ -0,0 +1,39 @@ +#include "FileFolderBar.h" +#include +namespace Toolbox { + FileFolderBar::FileFolderBar(QWidget *parent) : QWidget(parent) { + //setAttribute(Qt::WA_OpaquePaintEvent); + } + FileFolderBar::~FileFolderBar() { + } + void FileFolder::draw(int index, QPainter *painter) { + static QImage fileFolder = QImage(":fileFolder.png"); + int x = 10 + 20 * deep; + int y = 10 + 30 * index; +// painter->drawImage(x, y, fileFolder); + painter->drawImage(0, 0, fileFolder); + painter->drawText(x + 20, y + 10, mName); + } + void FileFolderBar::paintEvent(QPaintEvent *event) { + QWidget::paintEvent(event); + QPainter painter(this); + int index = 0; + for (FileFolder *&root: roots) { + QQueue que; + root->deep = 0; + que.enqueue(root); + while (!que.empty()) { + FileFolder *cur = que.dequeue(); + int n = cur->sons.size(); + cur->draw(index++, &painter); + for (int i = 0; i < n; ++i) { + if (cur->isShowSons) { + cur->sons[i]->deep = cur->deep + 1; + que.enqueue(cur->sons[i]); + } + } + } + } + painter.end(); + } +} diff --git a/module/radio/Toolbox_private/view/FileFolderBar.h b/module/radio/Toolbox_private/view/FileFolderBar.h new file mode 100644 index 0000000..eafb6f7 --- /dev/null +++ b/module/radio/Toolbox_private/view/FileFolderBar.h @@ -0,0 +1,25 @@ +#ifndef Toolbox_FileFolderBar_H +#define Toolbox_FileFolderBar_H +#include +#include "../Node.hpp" +namespace Toolbox { + class FileFolder : public Node { + public: + QString mName; + bool isShowSons = false; + int deep = 0; + void draw(int index, QPainter *painter); + }; + class FileFolderBar : public QWidget, public NodeManager { + Q_OBJECT + public: + explicit FileFolderBar(QWidget *parent = nullptr); + ~FileFolderBar() override; + protected: + void paintEvent(QPaintEvent *event) override; + }; +} +#endif + + + diff --git a/module/radio/Toolbox_private/view/icon/FileFolder.qrc b/module/radio/Toolbox_private/view/icon/FileFolder.qrc new file mode 100644 index 0000000..86119ff --- /dev/null +++ b/module/radio/Toolbox_private/view/icon/FileFolder.qrc @@ -0,0 +1,6 @@ + + + fileFolder.png + arrowDown.png + + \ No newline at end of file diff --git a/module/radio/Toolbox_private/view/icon/arrowDown.png b/module/radio/Toolbox_private/view/icon/arrowDown.png new file mode 100644 index 0000000..b56a075 Binary files /dev/null and b/module/radio/Toolbox_private/view/icon/arrowDown.png differ diff --git a/module/radio/Toolbox_private/view/icon/fileFolder.png b/module/radio/Toolbox_private/view/icon/fileFolder.png new file mode 100644 index 0000000..68f2f79 Binary files /dev/null and b/module/radio/Toolbox_private/view/icon/fileFolder.png differ diff --git a/module/radio/component/AbstractTextButton.cpp b/module/radio/component/AbstractTextButton.cpp new file mode 100644 index 0000000..aa6bc53 --- /dev/null +++ b/module/radio/component/AbstractTextButton.cpp @@ -0,0 +1,17 @@ +#include +#include "AbstractTextButton.h" +#include + +AbstractTextButton::AbstractTextButton(QWidget *parent) : QWidget(parent) { +} + +void AbstractTextButton::paintEvent(QPaintEvent *event) { + QPainter painter(this); + painter.fillRect(rect(), Qt::red); + painter.end(); +} + +void AbstractTextButton::mousePressEvent(QMouseEvent *event) { + if(mClick) mClick(); + event->accept(); +} \ No newline at end of file diff --git a/module/radio/component/AbstractTextButton.h b/module/radio/component/AbstractTextButton.h new file mode 100644 index 0000000..6e1cbdd --- /dev/null +++ b/module/radio/component/AbstractTextButton.h @@ -0,0 +1,20 @@ +#ifndef AbstractTextButton_H +#define AbstractTextButton_H +#include "../Global.h" +class AbstractTextButton : public QWidget { +public: + explicit AbstractTextButton(QWidget *parent = nullptr); + QFont mFont; + QColor mBackgroundColor; + QColor mEnterColor; + QPen mPen; + bool mEnter = false; + std::function mClick = nullptr; +protected: + void paintEvent(QPaintEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; +}; +#endif + + + diff --git a/module/radio/component/ConsoleWidget.cpp b/module/radio/component/ConsoleWidget.cpp new file mode 100644 index 0000000..fa3134f --- /dev/null +++ b/module/radio/component/ConsoleWidget.cpp @@ -0,0 +1,2 @@ +#include "ConsoleWidget.h" + diff --git a/module/radio/component/ConsoleWidget.h b/module/radio/component/ConsoleWidget.h new file mode 100644 index 0000000..b06805c --- /dev/null +++ b/module/radio/component/ConsoleWidget.h @@ -0,0 +1,11 @@ +#ifndef ConsoleWidget_H +#define ConsoleWidget_H +#include "../Global.h" +#include +class ConsoleWidget : public QTextEdit { +public: +}; +#endif + + + diff --git a/module/radio/component/Electricity.cpp b/module/radio/component/Electricity.cpp new file mode 100644 index 0000000..3d317c4 --- /dev/null +++ b/module/radio/component/Electricity.cpp @@ -0,0 +1,11 @@ +#include "Electricity.h" +#include + +Electricity::Electricity(QWidget *parent) : QWidget(parent) { +} + +void Electricity::paintEvent(QPaintEvent *event) { + QPainter painter(this); + painter.fillRect(rect(), Qt::red); + painter.end(); +} diff --git a/module/radio/component/Electricity.h b/module/radio/component/Electricity.h new file mode 100644 index 0000000..52444cc --- /dev/null +++ b/module/radio/component/Electricity.h @@ -0,0 +1,13 @@ +#ifndef Electricity_H +#define Electricity_H +#include "../Global.h" +class Electricity : public QWidget { +public: + explicit Electricity(QWidget *parent = nullptr); +protected: + void paintEvent(QPaintEvent *event) override; +}; +#endif + + + diff --git a/module/radio/component/ExpandInput.cpp b/module/radio/component/ExpandInput.cpp new file mode 100644 index 0000000..e6d800e --- /dev/null +++ b/module/radio/component/ExpandInput.cpp @@ -0,0 +1,44 @@ +#include "ExpandInput.h" +#include "../BackEnd/MainWidget.h" +#include "YSGraphic_Core/base/export.h" +#include +#include +ExpandInput::ExpandInput(QWidget *parent) : QLineEdit(parent) { + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + setMinimumSize(0, 0); + setFrame(false); + mFont.setBold(true); + YSG::VirtualKeyBoard::instance()->setEdit(this); +} + +void ExpandInput::paintEvent(QPaintEvent *event) { +// QPainter painter(this); +// painter.fillRect(rect(), Qt::red); +// painter.end(); + QLineEdit::paintEvent(event); +} + +void ExpandInput::resizeEvent(QResizeEvent *event) { + int pixelSize = Global::instance()->adaptHeight(60); + QFont font = mFont; + font.setPixelSize(pixelSize); + setFont(font); + QWidget::resizeEvent(event); +} + +void ExpandInput::focusInEvent(QFocusEvent *event) { + setStyleSheet("QLineEdit { border: 4px dashed gray; }"); + update(); + event->accept(); +} + +void ExpandInput::focusOutEvent(QFocusEvent *event) { + setStyleSheet("QLineEdit { border: 0px dashed gray; }"); + QLineEdit::focusOutEvent(event); +} + +void ExpandInput::keyPressEvent(QKeyEvent *event) { + QLineEdit::keyPressEvent(event); + event->ignore(); +} + diff --git a/module/radio/component/ExpandInput.h b/module/radio/component/ExpandInput.h new file mode 100644 index 0000000..9dd25b6 --- /dev/null +++ b/module/radio/component/ExpandInput.h @@ -0,0 +1,20 @@ +#ifndef ExpandInput_H +#define ExpandInput_H +#include "../Global.h" +#include +class ExpandInput : public QLineEdit { +public: + explicit ExpandInput(QWidget *parent = nullptr); + QFont mFont; +protected: + void paintEvent(QPaintEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + void focusInEvent(QFocusEvent *event) override; + void focusOutEvent(QFocusEvent *event) override; + + void keyPressEvent(QKeyEvent *event) override; +}; +#endif + + + diff --git a/module/radio/component/FrequentShower.cpp b/module/radio/component/FrequentShower.cpp new file mode 100644 index 0000000..edf22c3 --- /dev/null +++ b/module/radio/component/FrequentShower.cpp @@ -0,0 +1,103 @@ +#include "FrequentShower.h" +#include +#include +#include +#include "../Global.h" + + + + +FrequentShower::FrequentShower(QWidget *parent) : QWidget(parent) { + setObjectName("设置频率值控件"); + setFrequent(BackEnd::instance()->YsGetFreq()); +} + +void FrequentShower::paintEvent(QPaintEvent *event) { + QPainter painter(this); + QFont font; + font.setPointSize(calculateOptimalFontSize(mFrequent, {(int)((double)width() * 0.9), height()}, font)); + painter.setFont(font); + painter.setPen(Qt::black); + painter.drawText(rect(), Qt::AlignCenter, mFrequent); + QFontMetrics fontMetrics(font); + if (selectIndex >= 0 && selectIndex < mFrequent.length()) { + int a = (QWidget::width() - fontMetrics.horizontalAdvance(mFrequent)) / 2; + int startX = a + fontMetrics.horizontalAdvance(mFrequent.mid(0, selectIndex)); + int w = fontMetrics.horizontalAdvance(mFrequent[selectIndex]); + painter.fillRect(startX, 0, w, QWidget::height(), Qt::black); + painter.setPen(Qt::white); + painter.drawText(QRect(startX, 0, w, QWidget::height()), Qt::AlignCenter, QString(mFrequent[selectIndex])); + } + +} + +void FrequentShower::keyPressEvent(QKeyEvent *event) { + BackEnd* g = BackEnd::instance(); + + QString keyText = event->text(); + if (keyText >= "0" && keyText <= "9") { + mFrequent[selectIndex] = keyText.at(0).toLatin1(); + update(); + return; + } + if (g->match(event, "左移")) { + move(-1); + } else if (g->match(event, "右移")) { + move(1); + } else if (g->match(event, "增加")) { + change(1); + } else if (g->match(event, "减小")) { + change(-1); + } + event->ignore(); + +} + +void FrequentShower::move(int num) { + selectIndex += num; + if(selectIndex < 0) { + selectIndex = 0; + } else if(selectIndex >= mFrequent.length()) { + selectIndex = mFrequent.length() - 1; + } + if(mFrequent[selectIndex] == '.') { + if(num > 0) { + selectIndex++; + } else { + selectIndex--; + } + } + update(); +} + +void FrequentShower::change(int num) { + if (selectIndex >= 0 && selectIndex < mFrequent.length()) { + int n = mFrequent[selectIndex].digitValue(); + n += num; + if (n < 0) { + n = 9; + } else if (n > 9) { + n = 0; + } + mFrequent[selectIndex] = QString::number(n)[0]; + update(); + BackEnd::instance()->YsSetFreq(QString(mFrequent).replace('.', "").toULongLong()); + } +} + +void FrequentShower::setFrequent(quint64 frequent) { + QString strNumber = QString::number(frequent, 10); + int padding = 11 - strNumber.length(); + if (padding > 0) { + strNumber = QString(padding, '0') + strNumber; + } + mFrequent = QString("%1.%2.%3.%4").arg( + strNumber.mid(0, 2), + strNumber.mid(2, 3), + strNumber.mid(5, 3), + strNumber.mid(8, 3) + ); +// qDebug() << strNumber << " " << mFrequent; + update(); +} + diff --git a/module/radio/component/FrequentShower.h b/module/radio/component/FrequentShower.h new file mode 100644 index 0000000..533eafa --- /dev/null +++ b/module/radio/component/FrequentShower.h @@ -0,0 +1,21 @@ +#ifndef FrequentShower_H +#define FrequentShower_H +#include "../Global.h" + +class FrequentShower : public QWidget { +public: + explicit FrequentShower(QWidget *parent = nullptr); + void setFrequent(quint64 frequent); + int selectIndex = 0; + QString mFrequent = "00.000.000.000"; +protected: + void paintEvent(QPaintEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + void move(int num); + void change(int num); +}; +#endif + + + + diff --git a/module/radio/component/ProgressBar.cpp b/module/radio/component/ProgressBar.cpp new file mode 100644 index 0000000..4fe79d1 --- /dev/null +++ b/module/radio/component/ProgressBar.cpp @@ -0,0 +1,88 @@ +#include "ProgressBar.h" +#include + +ProgressBar::ProgressBar(const QVector& tickList, QWidget *parent) : QWidget(parent), mTickList(tickList) { + setAttribute(Qt::WA_OpaquePaintEvent, true); + mTimer = startTimer(30); +} + +double ProgressBar::getDrawWidth(double value) { + int n = mTickList.size(); + int i = 1; + for(; i < n - 1; ++i) { + double cur = mTickList[i].mValue; + if(mValue < cur || qFuzzyCompare(mValue, cur)) { + break; + } + } + int lowerOffset = i - 1; + int upperOffset = i; + double lower = mTickList[lowerOffset].mValue; + double upper = mTickList[upperOffset].mValue; + double w_step = (double)QWidget::width()/(double)(n-1); + double lastRate = qMax(0.0, (mValue - lower)/(upper - lower)); + double drawWidth = w_step * (lastRate + lowerOffset); + QString ticks; + for(Tick& tick : mTickList) { + ticks.append(" " + QString::number(tick.mValue)); + } + // qDebug() << QString("%1->[%2,%3] i=%4 n=%5 drawWidth:%6 width:%7 ticks:%8 w_step:%9 lastRate:%10") + // .arg(mValue).arg(lower).arg(upper).arg(i).arg(n).arg(drawWidth).arg(width()).arg(ticks) + // .arg(w_step).arg(lastRate); + return drawWidth; +} + + + +void ProgressBar::paintEvent(QPaintEvent *event) { + QPainter painter(this); + painter.setPen(Qt::NoPen); + painter.fillRect(rect(), QApplication::style()->standardPalette().brush(QPalette::Window)); + painter.setPen(QPen(Qt::black)); + auto w = (double)QWidget::width(); + auto hh = (double)height()/2; + int n = mTickList.size(); + int tickW = 1; + double drawWidth = getDrawWidth(mValue); + // 背景 + painter.fillRect(0, 0, drawWidth - tickW - 4, height()/2, Qt::black); + int curX = 0; + // 进度条 + while(curX + tickW + 4 < drawWidth){ + painter.fillRect(curX, 0, tickW, height()/2, Qt::gray); + curX += tickW + (int)mTickSpaceW; + } + int lineY = (int)hh + 2; + painter.fillRect(curX -(int)mTickSpaceW , 0, 4, lineY - 0, Qt::yellow); + painter.drawLine(0, lineY , (int)w, lineY); + // 画刻度 + QFont font; + font.setBold(true); + QFontMetrics fm(font); + for(int i = 0; i < n; ++i){ + int tickX = (int)((double)(QWidget::width() * i)/(double)(n - 1)); + int textW = fm.horizontalAdvance( mTickList[i].mText); + int textX; + if(i == n - 1) { + textX = tickX - textW; + tickX -=1; + } else if( i == 0) { + textX = tickX; + } else { + textX = tickX - textW/2; + } + painter.setPen(Qt::black); + painter.drawLine(tickX, lineY, tickX, (lineY + 5)); + painter.setPen(mTickList[i].mColor); + painter.setFont(font); + painter.drawText(QRectF(textX, lineY, textW, lineY), Qt::AlignCenter, mTickList[i].mText); + } +} + +void ProgressBar::timerEvent(QTimerEvent *event) { + if(event->timerId() == mTimer) { + if(mSetValue) mSetValue(); + update(); + } + QObject::timerEvent(event); +} diff --git a/module/radio/component/ProgressBar.h b/module/radio/component/ProgressBar.h new file mode 100644 index 0000000..508214f --- /dev/null +++ b/module/radio/component/ProgressBar.h @@ -0,0 +1,37 @@ +#ifndef ProgressBar_H +#define ProgressBar_H +#include + +#include "../Global.h" + +struct Tick{ + QString mText; + QColor mColor; + double mValue = 0; + Tick(QString text, QColor color) : mText(std::move(text)), mColor(std::move(color)){ + QString that = (mText[0] == '+' || mText[0] == '-' || mText[0] == '<' || mText[0] == '>') ? mText.mid(1) : mText; + mValue = that.toDouble(); + } + Tick(QString text, QColor color, double value) : mText(std::move(text)), mColor(std::move(color)){ + mValue = value; + } +}; + + +class ProgressBar : public QWidget { +public: + explicit ProgressBar(const QVector& tickList, QWidget *parent = nullptr); + double mTickSpaceW = 1; + double mValue = 0; + int mTimer; + std::function mSetValue = nullptr; + double getDrawWidth(double value); +protected: + void paintEvent(QPaintEvent *event) override; + void timerEvent(QTimerEvent *event) override; + QVector mTickList; +}; +#endif + + + diff --git a/module/radio/component/ShowHelpInfo.cpp b/module/radio/component/ShowHelpInfo.cpp new file mode 100644 index 0000000..dc9b0a3 --- /dev/null +++ b/module/radio/component/ShowHelpInfo.cpp @@ -0,0 +1,27 @@ +#include "ShowHelpInfo.h" +#include "../Global.h" +#include +#include "../BackEnd/MainWidget.h" + +ShowHelpInfo::ShowHelpInfo(QWidget *parent) : QTextEdit(parent) { + setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); + setMinimumSize(0, 0); + setFrameStyle(0); + setCursorWidth(0); + setFocusPolicy(Qt::NoFocus); + setReadOnly(true); + setStyleSheet("color: black;"); + mFont.setBold(true); + setEnabled(false); +} + +//void ShowHelpInfo::paintEvent(QPaintEvent *event) { +// QTextEdit::paintEvent(event); +//} + +void ShowHelpInfo::resizeEvent(QResizeEvent *e) { + QFont font = mFont; + font.setPixelSize(Global::instance()->adaptHeight(mFont.pixelSize())); + setFont(font); + QTextEdit::resizeEvent(e); +} diff --git a/module/radio/component/ShowHelpInfo.h b/module/radio/component/ShowHelpInfo.h new file mode 100644 index 0000000..2dbf9ba --- /dev/null +++ b/module/radio/component/ShowHelpInfo.h @@ -0,0 +1,16 @@ +#ifndef ShowHelpInfo_H +#define ShowHelpInfo_H +#include "../Global.h" +#include +class ShowHelpInfo : public QTextEdit { +public: + explicit ShowHelpInfo(QWidget *parent = nullptr); + QFont mFont; +protected: +// void paintEvent(QPaintEvent *event) override; + void resizeEvent(QResizeEvent *e) override; +}; +#endif + + + diff --git a/module/radio/component/ShowTime.cpp b/module/radio/component/ShowTime.cpp new file mode 100644 index 0000000..9c2832c --- /dev/null +++ b/module/radio/component/ShowTime.cpp @@ -0,0 +1,23 @@ +#include "ShowTime.h" +#include +#include +#include + +ShowTime::ShowTime(QWidget *parent) : QWidget(parent) { + setObjectName("ShowTime"); + setAttribute(Qt::WA_OpaquePaintEvent); + mTimer.start(1000); + connect(&mTimer, &QTimer::timeout, this, [this](){ + update(); + }); +} + +void ShowTime::paintEvent(QPaintEvent *event) { + QPainter painter(this); + painter.setPen(Qt::NoPen); + painter.fillRect(rect(), QApplication::style()->standardPalette().brush(QPalette::Window)); + painter.setPen(QPen()); + QString&& dateTimeString = QDateTime::currentDateTime().toString("HH:mm:ss"); + painter.drawText(rect(), Qt::AlignCenter, dateTimeString); + painter.end(); +} diff --git a/module/radio/component/ShowTime.h b/module/radio/component/ShowTime.h new file mode 100644 index 0000000..a7ff878 --- /dev/null +++ b/module/radio/component/ShowTime.h @@ -0,0 +1,15 @@ +#ifndef ShowTime_H +#define ShowTime_H +#include "../Global.h" +#include +class ShowTime : public QWidget { +public: + explicit ShowTime(QWidget *parent = nullptr); + QTimer mTimer; +protected: + void paintEvent(QPaintEvent *event) override; +}; +#endif + + + diff --git a/module/radio/component/TopMenuBar.cpp b/module/radio/component/TopMenuBar.cpp new file mode 100644 index 0000000..af37b2c --- /dev/null +++ b/module/radio/component/TopMenuBar.cpp @@ -0,0 +1,41 @@ +#include "TopMenuBar.h" +#include "../Global.h" +#include "ShowTime.h" +#include "../BackEnd/MainWidget.h" +#include "../BaseWidget.h" +#include "Wifi.h" + + +TopMenuBar::TopMenuBar(QWidget *parent) : QWidget(parent) { + int fontSize = 20; + mAM = createButton("AM", fontSize); + mATU = createButton("ATU", fontSize); + mVSQL = createButton("VSQL", fontSize); + mNB = createButton("NB", fontSize); + mNR = createButton("NR", fontSize); + mDNF = createButton("DNF", fontSize); + mPRE = createButton("PRE", fontSize); + mATT = createButton("ATT", fontSize); + mSPL = createButton("SPL", fontSize); + mFIL1 = createButton("FIL1", fontSize); + mAGC_A = createButton("AGC_A", fontSize); + mTextButtonList = new YSG::RollObject({mAM, mATU, mVSQL, mNB, mNR, mDNF, mPRE, mATT, mSPL, mFIL1, mAGC_A}, [](QPushButton* cur){ + + }, [](QPushButton* btn){ + + }, this); + mShowTime = new ShowTime; + mWifi = new Wifi; + QHBoxLayout* statusBar = mTextButtonList->hBoxLayout(2); + statusBar->addStretch(3); + statusBar->addWidget(mWifi, 1); + statusBar->addWidget(mShowTime, 1); + setLayout(statusBar); +} + +//void TopMenuBar::paintEvent(QPaintEvent *event) { +// QPainter painter(this); +// painter.fillRect(rect(), Qt::red); +// painter.end(); +//} + diff --git a/module/radio/component/TopMenuBar.h b/module/radio/component/TopMenuBar.h new file mode 100644 index 0000000..f1b0519 --- /dev/null +++ b/module/radio/component/TopMenuBar.h @@ -0,0 +1,24 @@ +#ifndef TopMenuBar_H +#define TopMenuBar_H +#include "../Global.h" +#include "YSGraphic_Core/base/export.h" + +class TopButton; +class ShowTime; +class Wifi; +class QPushButton; +class TopMenuBar : public QWidget, public YSG::SingletonWidget { +public: + explicit TopMenuBar(QWidget *parent = nullptr); + QPushButton *mAM, *mATU, *mVSQL, *mNB, *mNR, *mDNF, *mPRE, *mATT, *mSPL, *mFIL1, *mAGC_A; + Wifi* mWifi; + YSG::RollObject *mTextButtonList; + int index = 0; + ShowTime *mShowTime; +protected: +// void paintEvent(QPaintEvent *event) override; +}; +#endif + + + diff --git a/module/radio/component/Wifi.cpp b/module/radio/component/Wifi.cpp new file mode 100644 index 0000000..2610739 --- /dev/null +++ b/module/radio/component/Wifi.cpp @@ -0,0 +1,43 @@ +#include "Wifi.h" +#include "../Global.h" +#include +#include + +Wifi::Wifi(QWidget *parent) : QWidget(parent) { +} + + + + +void Wifi::paintEvent(QPaintEvent *event) { + QPainter painter(this); +// painter.fillRect(rect(), Qt::red); + QRect window(0, 0, 20, 10); + painter.setWindow(window); + double w = window.width(), h = window.height(); + QRect drawRect = getMaxRect(rect(), w / h); + painter.setViewport(drawRect); + double rate = 1.5; // wife宽度 : 间隙宽度 + double baseHeightRate = 0.2; + double spaceWidth = w/(1.0 * 4 + rate * 5); + double stripWidth = spaceWidth * rate; + double baseHeight = h * baseHeightRate; + double raiseHeight = h * (1.0 - baseHeightRate)/4.0; + double raiseWidth = spaceWidth + stripWidth; + QRect textRect = QRect(0, 0, (int)(raiseWidth * 2), (int)(baseHeight * 2)); + QFont font; + font.setPixelSize(5); + font.setBold(true); + painter.setFont(font); + QPen pen; + pen.setColor(Qt::white); + painter.setPen(pen); + painter.drawText(textRect, Qt::AlignJustify | Qt::AlignVCenter, "4G"); + for(int i = 0; i < 5; ++i){ + double curHeight = baseHeight + i * raiseHeight; + double curX = 0 + raiseWidth * i; + QColor color = i < value ? Qt::white : QColor(0, 0, 0, 50); + painter.fillRect(QRectF(curX, h - curHeight, stripWidth, curHeight), color); + } + painter.end(); +} diff --git a/module/radio/component/Wifi.h b/module/radio/component/Wifi.h new file mode 100644 index 0000000..84b7e73 --- /dev/null +++ b/module/radio/component/Wifi.h @@ -0,0 +1,14 @@ +#ifndef Wifi_H +#define Wifi_H +#include "../Global.h" +class Wifi : public QWidget { +public: + explicit Wifi(QWidget *parent = nullptr); + int value = 3; +protected: + void paintEvent(QPaintEvent *event) override; +}; +#endif + + + diff --git a/module/radio/main.cpp b/module/radio/main.cpp new file mode 100644 index 0000000..0bf3686 --- /dev/null +++ b/module/radio/main.cpp @@ -0,0 +1,31 @@ +#include +#ifdef _WIN32 +#include +#include +#endif +#include "./BackEnd/MainWidget.h" +#include "Application.h" +#include "YSGraphic_Core/base/Plot.h" + + +int main(int argc, char *argv[]) { + Application app(argc, argv); + Application::setAttribute(Qt::AA_UseHighDpiPixmaps); + BackEnd::instance(); + QFile file(":/qss/ElegantDark.qss"); + file.open(QIODevice::ReadOnly); + QString stylesheet = QLatin1String(file.readAll()); + file.close(); + app.setStyleSheet(stylesheet); + QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); +#ifdef _WINDOWS + SetConsoleOutputCP(CP_UTF8); + system("chcp 65001"); + //setbuf(stdout, 0); +#endif + MainWidget w; + app.mMainWidget = &w; + w.show(); + YSG::startAllRenderThread(); + return QApplication::exec(); +} diff --git a/module/radio/menu/BaseWidgetMenu.cpp b/module/radio/menu/BaseWidgetMenu.cpp new file mode 100644 index 0000000..9bc103b --- /dev/null +++ b/module/radio/menu/BaseWidgetMenu.cpp @@ -0,0 +1,158 @@ +#include "BaseWidgetMenu.h" +#include "../BaseWidget.h" +#include +#include "../BackEnd/MainWidget.h" + + + +BaseWidgetMenu::BaseWidgetMenu(QWidget* parent) : QWidget(parent){ + setObjectName("BaseWidgetMenu"); + setAttribute(Qt::WA_OpaquePaintEvent); + mMainLayout = new QVBoxLayout(this); + mFirstLayout = new QHBoxLayout(); + mMainLayout->addLayout(mFirstLayout, 1); + mSecondLayout = new QHBoxLayout(); + mMainLayout->addLayout(mSecondLayout, 1); + mRollObject.mEnterFunc = [](AbstractMenuButton* btn){ + btn->setChecked(true); + }; + mRollObject.mLeaveFunc = [](AbstractMenuButton* btn){ + btn->setChecked(false); + }; + hide(); +} + +void BaseWidgetMenu::paintEvent(QPaintEvent *event) { + QPainter painter(this); + painter.setPen(Qt::NoPen); + QPalette palette = QApplication::style()->standardPalette(); + const QBrush& base1Brush = palette.brush(QPalette::Window); + painter.setBrush(base1Brush); + painter.drawRect(rect()); + painter.end(); +} + +void BaseWidgetMenu::hideEvent(QHideEvent *event) { + for(auto btn : sons){ + btn->hide(); + } + emit hideThat(); + event->accept(); +} + +void BaseWidgetMenu::showEvent(QShowEvent *event) { + if(!mRollObject.mWidgets.empty()) mRollObject.mEnterFunc(mRollObject.cur()); + emit showThat(); + event->accept(); +} + +void BaseWidgetMenu::addMenuButtonOnLayout1(const QVector& buttons, int stretch) { + for(AbstractMenuButton* btn : buttons){ + mFirstLayout->addWidget(btn, 1); + mRollObject.mWidgets.push_back(btn); + btn->mParentMenu = this; + } + if(stretch != 0) { + mFirstLayout->addStretch(stretch); + mFirstLayout->addSpacing(mSecondLayout->spacing() * stretch); + }; +} + +void BaseWidgetMenu::addMenuButtonOnLayout2(const QVector& buttons, int stretch) { + for(AbstractMenuButton* btn : buttons){ + mSecondLayout->addWidget(btn, 1); + mRollObject.mWidgets.push_back(btn); + btn->mParentMenu = this; + } + + if(stretch != 0) { + mSecondLayout->addStretch(stretch); + mSecondLayout->addSpacing(mSecondLayout->spacing() * stretch); + }; +} + +void BaseWidgetMenu::addMenuButtonOnLayout1(const QVector& buttons) { + addMenuButtonOnLayout1(buttons, 5 - buttons.size()); +} + +void BaseWidgetMenu::addMenuButtonOnLayout2(const QVector& buttons) { + addMenuButtonOnLayout2(buttons, 5 - buttons.size()); +} + +BaseWidgetMenu* BaseWidgetMenu::createSubWidgetMenu(AbstractMenuButton *btn) { + auto ret = new BaseWidgetMenu(parentWidget()); + ret->parentBtn = btn; + ret->hide(); + ret->father = this; + sons.push_back(ret); + btn->mOwnMenu = ret; + return ret; +} + + + + + +void BaseWidgetMenu::keyPressEvent(QKeyEvent *event) { + BackEnd* g = BackEnd::instance(); + if (g->match(event, "右移")) { + mRollObject.rollRight(); + } + else if (g->match(event, "左移")) { + mRollObject.rollLeft(); + } + else if (g->match(event, "增加")) { + auto v = dynamic_cast(mRollObject.cur()); + if(v){ + v->mValueChanged(v, true); + } + } + else if (g->match(event, "减小")) { + auto v = dynamic_cast(mRollObject.cur()); + if(v){ + v->mValueChanged(v, false); + } + } + else if (g->match(event, "确定")){ + confirm(); + } + else if (g->match(event, "退出")){ + esc(this); + return; + } + event->ignore(); +} + + + +void BaseWidgetMenu::confirm() { + BaseWidgetMenu* m = mRollObject.cur()->mOwnMenu; + if(m){ + m->resize(size()); + m->move(geometry().topLeft() + QPoint(0, -height())); + m->raise(); + m->setFocus(); + m->show(); + } else { + mRollObject.cur()->emit clicked(); + if(mRollObject.cur()->mClickHide){ + rootNode()->hide(); + } + } +} + + +void BaseWidgetMenu::esc(BaseWidgetMenu* menu){ + if(menu->root()){ + MainWidget::instance()->getCurrentBaseWidget()->setFocus(); + } else { + menu->father->setFocus(); + } + menu->hide(); +} + + +void AbstractMenuButton::hideRoot() { + MainWidget::instance()->getCurrentBaseWidget()->setFocus(); + mParentMenu->rootNode()->hide(); +} diff --git a/module/radio/menu/BaseWidgetMenu.h b/module/radio/menu/BaseWidgetMenu.h new file mode 100644 index 0000000..0de05cd --- /dev/null +++ b/module/radio/menu/BaseWidgetMenu.h @@ -0,0 +1,148 @@ +#ifndef BaseWidgetMenu_H +#define BaseWidgetMenu_H +#include "YSGraphic_Core/base/Node.hpp" +#include "YSGraphic_Core/base/RollObject.h" +#include "YSGraphic_Core/export.h" + +#include +#include +#include + +class QHBoxLayout; +class QVBoxLayout; +class AbstractTextButton; +class AbstractMenuButton; + + +class BaseWidgetMenu : public QWidget, public YSG::Node { + Q_OBJECT +public: + explicit BaseWidgetMenu(QWidget* parent); + QVBoxLayout *mMainLayout; + QHBoxLayout *mFirstLayout; + QHBoxLayout *mSecondLayout; + AbstractMenuButton *parentBtn{}; + YSG::RollObject mRollObject; + BaseWidgetMenu* createSubWidgetMenu(AbstractMenuButton * btn); + void esc(BaseWidgetMenu* menu); + void confirm(); + void addMenuButtonOnLayout1(const QVector& buttons, int stretch); + void addMenuButtonOnLayout2(const QVector& buttons, int stretch); + void addMenuButtonOnLayout1(const QVector& buttons); + void addMenuButtonOnLayout2(const QVector& buttons); +signals: + void showThat(); + void hideThat(); +protected: + void paintEvent(QPaintEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + void showEvent(QShowEvent *event) override; + void hideEvent(QHideEvent *event) override; +}; + +class AbstractMenuButton : public QPushButton { +public: + AbstractMenuButton() = default; + BaseWidgetMenu *mParentMenu{}; + BaseWidgetMenu *mOwnMenu{}; + bool mClickHide = true; + void init(int fontSize){ + setFocusPolicy(Qt::NoFocus); + setFlat(true); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + setCheckable(true); + setChecked(false); + QFont font; + font.setPixelSize(fontSize); + setFont(font); + } + + void mousePressEvent(QMouseEvent *e) override { + mParentMenu->mRollObject.setCur(this); + mParentMenu->confirm(); + } + + void hideRoot(); +}; + +class MenuButton : public AbstractMenuButton{ +public: + std::function mClick = nullptr; + MenuButton(const QString &text, int fontSize, const std::function &click){ + mClick = click; + setText(text); + init(fontSize); + connect(this, &AbstractMenuButton::clicked, [this](){ + mClick(); + }); + } +}; + +class DoubleTextMenuButton : public AbstractMenuButton{ +public: + std::function mSwitchClick = nullptr; + QString mText1, mText2; + bool mIsText1 = false; + DoubleTextMenuButton(const QString &text1, const QString &text2, int fontSize, const std::function &click){ + mClickHide = false; + mText1 = text1; + mText2 = text2; + mSwitchClick = click; + setText(text1); + init(fontSize); + connect(this, &AbstractMenuButton::clicked, [this](){ + mIsText1 = !mIsText1; + mSwitchClick(mIsText1); + if(mIsText1){ + setText(mText2); + } else { + setText(mText1); + } + }); + } +}; + +class ValueMenuButton : public AbstractMenuButton{ +public: + double mValue{}; + QString mText; + std::function mValueChanged; + void setValue(double value){ + mValue = value; + setText(mText.arg(mValue)); + } + ValueMenuButton(const QString &text, int fontSize, + const std::function &valueChanged, double firstValue) { + mText = text; + init(fontSize); + mValueChanged = valueChanged; + setValue(firstValue); + } +}; + +// class ValueMenuButton : public AbstractMenuButton{ +// public: +// std::function mHandleUp = nullptr; +// std::function mHandleDown = nullptr; +// QString mText; +// double mValue{}; +// ValueMenuButton(const QString &text, int fontSize, +// const std::function &handleUp, +// const std::function &handleDown){ +// mClickHide = false; +// mText = text; +// mHandleUp = handleUp; +// mHandleDown = handleDown; +// setValue(mValue); +// init(fontSize); +// } +// void setValue(double value){ +// mValue = value; +// setText(mText.arg(mValue)); +// } +// }; + +#endif + + + diff --git a/module/radio/styles/AbstractStyle.cpp b/module/radio/styles/AbstractStyle.cpp new file mode 100644 index 0000000..cc39098 --- /dev/null +++ b/module/radio/styles/AbstractStyle.cpp @@ -0,0 +1,3 @@ +#include "AbstractStyle.h" +#include + diff --git a/module/radio/styles/AbstractStyle.h b/module/radio/styles/AbstractStyle.h new file mode 100644 index 0000000..e199bd6 --- /dev/null +++ b/module/radio/styles/AbstractStyle.h @@ -0,0 +1,18 @@ +#ifndef AbstractStyle_H +#define AbstractStyle_H +#include +class AbsWidget { +public: + int mType; +}; + +template +class AbsExWidget : public Base, public AbsWidget { +public: + template + explicit AbsExWidget(Params... params) : Base(params...) {} +}; +#endif + + + diff --git a/module/radio/styles/images/woodbackground.png b/module/radio/styles/images/woodbackground.png new file mode 100644 index 0000000..e69de29 diff --git a/module/radio/styles/images/woodbutton.png b/module/radio/styles/images/woodbutton.png new file mode 100644 index 0000000..e69de29 diff --git a/module/radio/styles/norwegianwoodstyle.cpp b/module/radio/styles/norwegianwoodstyle.cpp new file mode 100644 index 0000000..b28141a --- /dev/null +++ b/module/radio/styles/norwegianwoodstyle.cpp @@ -0,0 +1,224 @@ +#include "norwegianwoodstyle.h" +#include +#include +#include +#include +#include +#include +#include + +NorwegianWoodStyle::NorwegianWoodStyle() : + QProxyStyle(QStyleFactory::create("windows")) { + setObjectName("NorwegianWood"); +} + +//! [0] +QPalette NorwegianWoodStyle::standardPalette() const { + if (!m_standardPalette.isBrushSet(QPalette::Disabled, QPalette::Mid)) { + QColor brown(212, 140, 95); + QColor beige(236, 182, 120); + QColor slightlyOpaqueBlack(0, 0, 0, 63); + QImage backgroundImage(":/images/woodbackground.png"); + QImage buttonImage(":/images/woodbutton.png"); + QImage midImage = buttonImage.convertToFormat(QImage::Format_RGB32); + QPainter painter; + painter.begin(&midImage); + painter.setPen(Qt::NoPen); + painter.fillRect(midImage.rect(), slightlyOpaqueBlack); + painter.end(); + QPalette palette(brown); + palette.setBrush(QPalette::BrightText, Qt::white); + palette.setBrush(QPalette::Base, beige); + palette.setBrush(QPalette::Highlight, Qt::darkGreen); + setTexture(palette, QPalette::Button, buttonImage); + setTexture(palette, QPalette::Mid, midImage); + setTexture(palette, QPalette::Window, backgroundImage); + QBrush brush = palette.window(); + brush.setColor(brush.color().darker()); + palette.setBrush(QPalette::Disabled, QPalette::WindowText, brush); + palette.setBrush(QPalette::Disabled, QPalette::Text, brush); + palette.setBrush(QPalette::Disabled, QPalette::ButtonText, brush); + palette.setBrush(QPalette::Disabled, QPalette::Base, brush); + palette.setBrush(QPalette::Disabled, QPalette::Button, brush); + palette.setBrush(QPalette::Disabled, QPalette::Mid, brush); + m_standardPalette = palette; + } + return m_standardPalette; +} + +void NorwegianWoodStyle::polish(QWidget *widget) { + if (qobject_cast(widget) + || qobject_cast(widget)) + widget->setAttribute(Qt::WA_Hover, true); +} + +void NorwegianWoodStyle::unpolish(QWidget *widget) { + if (qobject_cast(widget) + || qobject_cast(widget)) + widget->setAttribute(Qt::WA_Hover, false); +} + +int NorwegianWoodStyle::pixelMetric(PixelMetric metric, + const QStyleOption *option, + const QWidget *widget) const { + switch (metric) { + case PM_ComboBoxFrameWidth: + return 8; + case PM_ScrollBarExtent: + return QProxyStyle::pixelMetric(metric, option, widget) + 4; + default: + return QProxyStyle::pixelMetric(metric, option, widget); + } +} + +int NorwegianWoodStyle::styleHint(StyleHint hint, const QStyleOption *option, + const QWidget *widget, + QStyleHintReturn *returnData) const { + switch (hint) { + case SH_DitherDisabledText: + return int(false); + case SH_EtchDisabledText: + return int(true); + default: + return QProxyStyle::styleHint(hint, option, widget, returnData); + } +} + +void NorwegianWoodStyle::drawPrimitive(PrimitiveElement element, + const QStyleOption *option, + QPainter *painter, + const QWidget *widget) const { + switch (element) { + case PE_PanelButtonCommand: { + int delta = (option->state & State_MouseOver) ? 64 : 0; + QColor slightlyOpaqueBlack(0, 0, 0, 63); + QColor semiTransparentWhite(255, 255, 255, 127 + delta); + QColor semiTransparentBlack(0, 0, 0, 127 - delta); + int x, y, width, height; + option->rect.getRect(&x, &y, &width, &height); + QPainterPath roundRect = roundRectPath(option->rect); + int radius = qMin(width, height) / 2; + QBrush brush; + bool darker; + const QStyleOptionButton *buttonOption = + qstyleoption_cast(option); + if (buttonOption + && (buttonOption->features & QStyleOptionButton::Flat)) { + brush = option->palette.window(); + darker = (option->state & (State_Sunken | State_On)); + } else { + if (option->state & (State_Sunken | State_On)) { + brush = option->palette.mid(); + darker = !(option->state & State_Sunken); + } else { + brush = option->palette.button(); + darker = false; + } + } + painter->save(); + painter->setRenderHint(QPainter::Antialiasing, true); + painter->fillPath(roundRect, brush); + if (darker) + painter->fillPath(roundRect, slightlyOpaqueBlack); + int penWidth; + if (radius < 10) + penWidth = 3; + else if (radius < 20) + penWidth = 5; + else + penWidth = 7; + QPen topPen(semiTransparentWhite, penWidth); + QPen bottomPen(semiTransparentBlack, penWidth); + if (option->state & (State_Sunken | State_On)) + qSwap(topPen, bottomPen); + int x1 = x; + int x2 = x + radius; + int x3 = x + width - radius; + int x4 = x + width; + if (option->direction == Qt::RightToLeft) { + qSwap(x1, x4); + qSwap(x2, x3); + } + QPolygon topHalf; + topHalf << QPoint(x1, y) + << QPoint(x4, y) + << QPoint(x3, y + radius) + << QPoint(x2, y + height - radius) + << QPoint(x1, y + height); + painter->setClipPath(roundRect); + painter->setClipRegion(topHalf, Qt::IntersectClip); + painter->setPen(topPen); + painter->drawPath(roundRect); + QPolygon bottomHalf = topHalf; + bottomHalf[0] = QPoint(x4, y + height); + painter->setClipPath(roundRect); + painter->setClipRegion(bottomHalf, Qt::IntersectClip); + painter->setPen(bottomPen); + painter->drawPath(roundRect); + painter->setPen(option->palette.windowText().color()); + painter->setClipping(false); + painter->drawPath(roundRect); + painter->restore(); + } + break; + default: + QProxyStyle::drawPrimitive(element, option, painter, widget); + } +} + +void NorwegianWoodStyle::drawControl(ControlElement element, + const QStyleOption *option, + QPainter *painter, + const QWidget *widget) const { + switch (element) { + case CE_PushButtonLabel: { + QStyleOptionButton myButtonOption; + auto btn = (QPushButton*)(widget); + auto buttonOption = qstyleoption_cast(option); + if (buttonOption) { + myButtonOption = *buttonOption; + QBrush bright = myButtonOption.palette.brightText(); + if(!btn->isFlat()){ + myButtonOption.palette.setBrush(QPalette::ButtonText, bright); + } + if (myButtonOption.palette.currentColorGroup() + != QPalette::Disabled) { + if (myButtonOption.state & (State_Sunken | State_On)) { + myButtonOption.palette.setBrush(QPalette::ButtonText, bright); + } + } + } + QProxyStyle::drawControl(element, &myButtonOption, painter, widget); + } + break; + default: + QProxyStyle::drawControl(element, option, painter, widget); + } +} + +void NorwegianWoodStyle::setTexture(QPalette &palette, QPalette::ColorRole role, + const QImage &image) { + for (int i = 0; i < QPalette::NColorGroups; ++i) { + QBrush brush(image); + brush.setColor(palette.brush(QPalette::ColorGroup(i), role).color()); + palette.setBrush(QPalette::ColorGroup(i), role, brush); + } +} + +QPainterPath NorwegianWoodStyle::roundRectPath(const QRect &rect) { + int radius = qMin(rect.width(), rect.height()) / 4; + int diam = 2 * radius; + int x1, y1, x2, y2; + rect.getCoords(&x1, &y1, &x2, &y2); + QPainterPath path; + path.moveTo(x2, y1 + radius); + path.arcTo(QRect(x2 - diam, y1, diam, diam), 0.0, +90.0); + path.lineTo(x1 + radius, y1); + path.arcTo(QRect(x1, y1, diam, diam), 90.0, +90.0); + path.lineTo(x1, y2 - radius); + path.arcTo(QRect(x1, y2 - diam, diam, diam), 180.0, +90.0); + path.lineTo(x1 + radius, y2); + path.arcTo(QRect(x2 - diam, y2 - diam, diam, diam), 270.0, +90.0); + path.closeSubpath(); + return path; +} diff --git a/module/radio/styles/norwegianwoodstyle.h b/module/radio/styles/norwegianwoodstyle.h new file mode 100644 index 0000000..117203b --- /dev/null +++ b/module/radio/styles/norwegianwoodstyle.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef NORWEGIANWOODSTYLE_H +#define NORWEGIANWOODSTYLE_H + +#include +#include + +QT_BEGIN_NAMESPACE +class QPainterPath; +QT_END_NAMESPACE + +//挪威森林风格 +//! [0] +class NorwegianWoodStyle : public QProxyStyle +{ + Q_OBJECT + +public: + NorwegianWoodStyle(); + + QPalette standardPalette() const override; + + void polish(QWidget *widget) override; + void unpolish(QWidget *widget) override; + int pixelMetric(PixelMetric metric, const QStyleOption *option, + const QWidget *widget) const override; + int styleHint(StyleHint hint, const QStyleOption *option, + const QWidget *widget, QStyleHintReturn *returnData) const override; + void drawPrimitive(PrimitiveElement element, const QStyleOption *option, + QPainter *painter, const QWidget *widget) const override; + void drawControl(ControlElement control, const QStyleOption *option, + QPainter *painter, const QWidget *widget) const override; + +private: + static void setTexture(QPalette &palette, QPalette::ColorRole role, + const QImage &image); + static QPainterPath roundRectPath(const QRect &rect); + mutable QPalette m_standardPalette; +}; +//! [0] + +#endif diff --git a/module/radio/styles/qss/AMOLED.qss b/module/radio/styles/qss/AMOLED.qss new file mode 100644 index 0000000..0083acb --- /dev/null +++ b/module/radio/styles/qss/AMOLED.qss @@ -0,0 +1,576 @@ +/* +AMOLED Style Sheet for QT Applications +Author: Jaime A. Quiroga P. +Company: GTRONICK +Last updated: 01/10/2021, 15:49. +Available at: https://github.com/GTRONICK/QSS/blob/master/AMOLED.qss +*/ +QMainWindow { + background-color:#000000; +} +QDialog { + background-color:#000000; +} +QColorDialog { + background-color:#000000; +} +QTextEdit { + background-color:#000000; + color: #a9b7c6; +} +QPlainTextEdit { + selection-background-color:#f39c12; + background-color:#000000; + border: 1px solid #FF00FF; + color: #a9b7c6; +} +QPushButton{ + border: 1px transparent; + color: #a9b7c6; + padding: 2px; + background-color: #000000; +} +QPushButton::default{ + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: #e67e22; + border-width: 1px; + color: #a9b7c6; + padding: 2px; + background-color: #000000; +} +QPushButton:hover{ + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: #FF00FF; + border-bottom-width: 1px; + border-bottom-radius: 6px; + border-style: solid; + color: #FFFFFF; + padding-bottom: 2px; + background-color: #000000; +} +QPushButton:pressed{ + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: #FF00FF; + border-bottom-width: 2px; + border-bottom-radius: 6px; + border-style: solid; + color: #e67e22; + padding-bottom: 1px; + background-color: #000000; +} +QPushButton:disabled{ + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: transparent; + border-bottom-width: 2px; + border-bottom-radius: 6px; + border-style: solid; + color: #808086; + padding-bottom: 1px; + background-color: #000000; +} +QToolButton { + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: #e67e22; + border-bottom-width: 1px; + border-style: solid; + color: #a9b7c6; + padding: 2px; + background-color: #000000; +} +QToolButton:hover{ + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: #e67e22; + border-bottom-width: 2px; + border-bottom-radius: 6px; + border-style: solid; + color: #FFFFFF; + padding-bottom: 1px; + background-color: #000000; +} +QLineEdit { + border-width: 1px; border-radius: 4px; + border-color: rgb(58, 58, 58); + border-style: inset; + padding: 0 8px; + color: #a9b7c6; + background:#000000; + selection-background-color:#007b50; + selection-color: #FFFFFF; +} +QLabel { + color: #a9b7c6; +} +QLCDNumber { + color: #e67e22; +} +QProgressBar { + text-align: center; + color: rgb(240, 240, 240); + border-width: 1px; + border-radius: 10px; + border-color: rgb(58, 58, 58); + border-style: inset; + background-color:#000000; +} +QProgressBar::chunk { + background-color: #e67e22; + border-radius: 5px; +} +QMenu{ + background-color:#000000; +} +QMenuBar { + background:rgb(0, 0, 0); + color: #a9b7c6; +} +QMenuBar::item { + spacing: 3px; + padding: 1px 4px; + background: transparent; +} +QMenuBar::item:selected { + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: #e67e22; + border-bottom-width: 1px; + border-bottom-radius: 6px; + border-style: solid; + color: #FFFFFF; + padding-bottom: 0px; + background-color: #000000; +} +QMenu::item:selected { + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: #e67e22; + border-bottom-color: transparent; + border-left-width: 2px; + color: #FFFFFF; + padding-left:15px; + padding-top:4px; + padding-bottom:4px; + padding-right:7px; + background-color:#000000; +} +QMenu::item { + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: transparent; + border-bottom-width: 1px; + border-style: solid; + color: #a9b7c6; + padding-left:17px; + padding-top:4px; + padding-bottom:4px; + padding-right:7px; + background-color:#000000; +} +QTabWidget { + color:rgb(0,0,0); + background-color:#000000; +} +QTabWidget::pane { + border-color: rgb(77,77,77); + background-color:#000000; + border-style: solid; + border-width: 1px; + border-radius: 6px; +} +QTabBar::tab { + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: transparent; + border-bottom-width: 1px; + border-style: solid; + color: #808086; + padding: 3px; + margin-left:3px; + background-color:#000000; +} +QTabBar::tab:selected, QTabBar::tab:last:selected, QTabBar::tab:hover { + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: #e67e22; + border-bottom-width: 2px; + border-style: solid; + color: #FFFFFF; + padding-left: 3px; + padding-bottom: 2px; + margin-left:3px; + background-color:#000000; +} + +QCheckBox { + color: #a9b7c6; + padding: 2px; +} +QCheckBox:disabled { + color: #808086; + padding: 2px; +} + +QCheckBox:hover { + border-radius:4px; + border-style:solid; + padding-left: 1px; + padding-right: 1px; + padding-bottom: 1px; + padding-top: 1px; + border-width:1px; + border-color: rgb(87, 97, 106); + background-color:#000000; +} +QCheckBox::indicator:checked { + + height: 10px; + width: 10px; + border-style:solid; + border-width: 1px; + border-color: #e67e22; + color: #a9b7c6; + background-color: #e67e22; +} +QCheckBox::indicator:unchecked { + + height: 10px; + width: 10px; + border-style:solid; + border-width: 1px; + border-color: #e67e22; + color: #a9b7c6; + background-color: transparent; +} +QRadioButton { + color: #a9b7c6; + background-color:#000000; + padding: 1px; +} +QRadioButton::indicator:checked { + height: 10px; + width: 10px; + border-style:solid; + border-radius:5px; + border-width: 1px; + border-color: #e67e22; + color: #a9b7c6; + background-color: #e67e22; +} +QRadioButton::indicator:!checked { + height: 10px; + width: 10px; + border-style:solid; + border-radius:5px; + border-width: 1px; + border-color: #e67e22; + color: #a9b7c6; + background-color: transparent; +} +QStatusBar { + color:#34e8eb; +} +QSpinBox { + color: #a9b7c6; + background-color:#000000; +} +QDoubleSpinBox { + color: #a9b7c6; + background-color:#000000; +} +QTimeEdit { + color: #a9b7c6; + background-color:#000000; +} +QDateTimeEdit { + color: #a9b7c6; + background-color:#000000; +} +QDateEdit { + color: #a9b7c6; + background-color:#000000; +} +QComboBox { + color: #a9b7c6; + background: #1e1d23; +} +QComboBox:editable { + background: #1e1d23; + color: #a9b7c6; + selection-background-color:#000000; +} +QComboBox QAbstractItemView { + color: #a9b7c6; + background: #1e1d23; + selection-color: #FFFFFF; + selection-background-color:#000000; +} +QComboBox:!editable:on, QComboBox::drop-down:editable:on { + color: #a9b7c6; + background: #1e1d23; +} +QFontComboBox { + color: #a9b7c6; + background-color:#000000; +} +QToolBox { + color: #a9b7c6; + background-color:#000000; +} +QToolBox::tab { + color: #a9b7c6; + background-color:#000000; +} +QToolBox::tab:selected { + color: #FFFFFF; + background-color:#000000; +} +QScrollArea { + color: #FFFFFF; + background-color:#000000; +} +QSlider::groove:horizontal { + height: 5px; + background: #e67e22; +} +QSlider::groove:vertical { + width: 5px; + background: #e67e22; +} +QSlider::handle:horizontal { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #b4b4b4, stop:1 #8f8f8f); + border: 1px solid #5c5c5c; + width: 14px; + margin: -5px 0; + border-radius: 7px; +} +QSlider::handle:vertical { + background: qlineargradient(x1:1, y1:1, x2:0, y2:0, stop:0 #b4b4b4, stop:1 #8f8f8f); + border: 1px solid #5c5c5c; + height: 14px; + margin: 0 -5px; + border-radius: 7px; +} +QSlider::add-page:horizontal { + background: white; +} +QSlider::add-page:vertical { + background: white; +} +QSlider::sub-page:horizontal { + background: #e67e22; +} +QSlider::sub-page:vertical { + background: #e67e22; +} +QScrollBar:horizontal { + max-height: 20px; + background: rgb(0,0,0); + border: 1px transparent grey; + margin: 0px 20px 0px 20px; +} +QScrollBar::handle:horizontal { + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgba(255, 0, 0, 0), stop:0.7 rgba(255, 0, 0, 0), stop:0.71 rgb(230, 126, 34), stop:1 rgb(230, 126, 34)); + border-style: solid; + border-width: 1px; + border-color: rgb(0,0,0); + min-width: 25px; +} +QScrollBar::handle:horizontal:hover { + background: rgb(230, 126, 34); + border-style: solid; + border-width: 1px; + border-color: rgb(0,0,0); + min-width: 25px; +} +QScrollBar::add-line:horizontal { + border: 1px solid; + border-color: rgb(0,0,0); + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgba(255, 0, 0, 0), stop:0.7 rgba(255, 0, 0, 0), stop:0.71 rgb(230, 126, 34), stop:1 rgb(230, 126, 34)); + width: 20px; + subcontrol-position: right; + subcontrol-origin: margin; +} +QScrollBar::add-line:horizontal:hover { + border: 1px solid; + border-color: rgb(0,0,0); + border-radius: 8px; + background: rgb(230, 126, 34); + height: 16px; + width: 16px; + subcontrol-position: right; + subcontrol-origin: margin; +} +QScrollBar::add-line:horizontal:pressed { + border: 1px solid; + border-color: grey; + border-radius: 8px; + background: rgb(230, 126, 34); + height: 16px; + width: 16px; + subcontrol-position: right; + subcontrol-origin: margin; +} +QScrollBar::sub-line:horizontal { + border: 1px solid; + border-color: rgb(0,0,0); + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgba(255, 0, 0, 0), stop:0.7 rgba(255, 0, 0, 0), stop:0.71 rgb(230, 126, 34), stop:1 rgb(230, 126, 34)); + width: 20px; + subcontrol-position: left; + subcontrol-origin: margin; +} +QScrollBar::sub-line:horizontal:hover { + border: 1px solid; + border-color: rgb(0,0,0); + border-radius: 8px; + background: rgb(230, 126, 34); + height: 16px; + width: 16px; + subcontrol-position: left; + subcontrol-origin: margin; +} +QScrollBar::sub-line:horizontal:pressed { + border: 1px solid; + border-color: grey; + border-radius: 8px; + background: rgb(230, 126, 34); + height: 16px; + width: 16px; + subcontrol-position: left; + subcontrol-origin: margin; +} +QScrollBar::left-arrow:horizontal { + border: 1px transparent grey; + border-radius: 3px; + width: 6px; + height: 6px; + background: rgb(0,0,0); +} +QScrollBar::right-arrow:horizontal { + border: 1px transparent grey; + border-radius: 3px; + width: 6px; + height: 6px; + background: rgb(0,0,0); +} +QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal { + background: none; +} +QScrollBar:vertical { + max-width: 20px; + background: rgb(0,0,0); + border: 1px transparent grey; + margin: 20px 0px 20px 0px; +} +QScrollBar::add-line:vertical { + border: 1px solid; + border-color: rgb(0,0,0); + background-color: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 0, 0, 0), stop:0.7 rgba(255, 0, 0, 0), stop:0.71 rgb(230, 126, 34), stop:1 rgb(230, 126, 34)); + height: 20px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} +QScrollBar::add-line:vertical:hover { + border: 1px solid; + border-color: rgb(0,0,0); + border-radius: 8px; + background: rgb(230, 126, 34); + height: 16px; + width: 16px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} +QScrollBar::add-line:vertical:pressed { + border: 1px solid; + border-color: grey; + border-radius: 8px; + background: rgb(230, 126, 34); + height: 16px; + width: 16px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} +QScrollBar::sub-line:vertical { + border: 1px solid; + border-color: rgb(0,0,0); + background-color: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 0, 0, 0), stop:0.7 rgba(255, 0, 0, 0), stop:0.71 rgb(230, 126, 34), stop:1 rgb(230, 126, 34)); + height: 20px; + subcontrol-position: top; + subcontrol-origin: margin; +} +QScrollBar::sub-line:vertical:hover { + border: 1px solid; + border-color: rgb(0,0,0); + border-radius: 8px; + background: rgb(230, 126, 34); + height: 16px; + width: 16px; + subcontrol-position: top; + subcontrol-origin: margin; +} +QScrollBar::sub-line:vertical:pressed { + border: 1px solid; + border-color: grey; + border-radius: 8px; + background: rgb(230, 126, 34); + height: 16px; + width: 16px; + subcontrol-position: top; + subcontrol-origin: margin; +} + QScrollBar::handle:vertical { + background-color: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 0, 0, 0), stop:0.7 rgba(255, 0, 0, 0), stop:0.71 rgb(230, 126, 34), stop:1 rgb(230, 126, 34)); + border-style: solid; + border-width: 1px; + border-color: rgb(0,0,0); + min-height: 25px; +} +QScrollBar::handle:vertical:hover { + background: rgb(230, 126, 34); + border-style: solid; + border-width: 1px; + border-color: rgb(0,0,0); + min-heigth: 25px; +} +QScrollBar::up-arrow:vertical { + border: 1px transparent grey; + border-radius: 3px; + width: 6px; + height: 6px; + background: rgb(0,0,0); +} +QScrollBar::down-arrow:vertical { + border: 1px transparent grey; + border-radius: 3px; + width: 6px; + height: 6px; + background: rgb(0,0,0); +} +QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + background: none; +} diff --git a/module/radio/styles/qss/Aqua.qss b/module/radio/styles/qss/Aqua.qss new file mode 100644 index 0000000..cce4c77 --- /dev/null +++ b/module/radio/styles/qss/Aqua.qss @@ -0,0 +1,559 @@ +/* +Aqua Style Sheet for QT Applications +Author: Jaime A. Quiroga P. +Company: GTRONICK +Last updated: 22/01/2019, 07:55. +Available at: https://github.com/GTRONICK/QSS/blob/master/Aqua.qss +*/ +QMainWindow { + background-color:#ececec; +} +QTextEdit { + border-width: 1px; + border-style: solid; + border-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(0, 113, 255, 255), stop:1 rgba(91, 171, 252, 255)); +} +QPlainTextEdit { + border-width: 1px; + border-style: solid; + border-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(0, 113, 255, 255), stop:1 rgba(91, 171, 252, 255)); +} +QToolButton { + border-style: solid; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(215, 215, 215), stop:1 rgb(222, 222, 222)); + border-right-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(217, 217, 217), stop:1 rgb(227, 227, 227)); + border-left-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(227, 227, 227), stop:1 rgb(217, 217, 217)); + border-bottom-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(215, 215, 215), stop:1 rgb(222, 222, 222)); + border-width: 1px; + border-radius: 5px; + color: rgb(0,0,0); + padding: 2px; + background-color: rgb(255,255,255); +} +QToolButton:hover{ + border-style: solid; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(195, 195, 195), stop:1 rgb(222, 222, 222)); + border-right-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(197, 197, 197), stop:1 rgb(227, 227, 227)); + border-left-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(227, 227, 227), stop:1 rgb(197, 197, 197)); + border-bottom-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(195, 195, 195), stop:1 rgb(222, 222, 222)); + border-width: 1px; + border-radius: 5px; + color: rgb(0,0,0); + padding: 2px; + background-color: rgb(255,255,255); +} +QToolButton:pressed{ + border-style: solid; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(215, 215, 215), stop:1 rgb(222, 222, 222)); + border-right-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(217, 217, 217), stop:1 rgb(227, 227, 227)); + border-left-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(227, 227, 227), stop:1 rgb(217, 217, 217)); + border-bottom-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(215, 215, 215), stop:1 rgb(222, 222, 222)); + border-width: 1px; + border-radius: 5px; + color: rgb(0,0,0); + padding: 2px; + background-color: rgb(142,142,142); +} +QPushButton{ + border-style: solid; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(215, 215, 215), stop:1 rgb(222, 222, 222)); + border-right-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(217, 217, 217), stop:1 rgb(227, 227, 227)); + border-left-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(227, 227, 227), stop:1 rgb(217, 217, 217)); + border-bottom-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(215, 215, 215), stop:1 rgb(222, 222, 222)); + border-width: 1px; + border-radius: 5px; + color: rgb(0,0,0); + padding: 2px; + background-color: rgb(255,255,255); +} +QPushButton::default{ + border-style: solid; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(215, 215, 215), stop:1 rgb(222, 222, 222)); + border-right-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(217, 217, 217), stop:1 rgb(227, 227, 227)); + border-left-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(227, 227, 227), stop:1 rgb(217, 217, 217)); + border-bottom-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(215, 215, 215), stop:1 rgb(222, 222, 222)); + border-width: 1px; + border-radius: 5px; + color: rgb(0,0,0); + padding: 2px; + background-color: rgb(255,255,255); +} +QPushButton:hover{ + border-style: solid; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(195, 195, 195), stop:1 rgb(222, 222, 222)); + border-right-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(197, 197, 197), stop:1 rgb(227, 227, 227)); + border-left-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(227, 227, 227), stop:1 rgb(197, 197, 197)); + border-bottom-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(195, 195, 195), stop:1 rgb(222, 222, 222)); + border-width: 1px; + border-radius: 5px; + color: rgb(0,0,0); + padding: 2px; + background-color: rgb(255,255,255); +} +QPushButton:pressed{ + border-style: solid; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(215, 215, 215), stop:1 rgb(222, 222, 222)); + border-right-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(217, 217, 217), stop:1 rgb(227, 227, 227)); + border-left-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(227, 227, 227), stop:1 rgb(217, 217, 217)); + border-bottom-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(215, 215, 215), stop:1 rgb(222, 222, 222)); + border-width: 1px; + border-radius: 5px; + color: rgb(0,0,0); + padding: 2px; + background-color: rgb(142,142,142); +} +QPushButton:disabled{ + border-style: solid; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(215, 215, 215), stop:1 rgb(222, 222, 222)); + border-right-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(217, 217, 217), stop:1 rgb(227, 227, 227)); + border-left-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(227, 227, 227), stop:1 rgb(217, 217, 217)); + border-bottom-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(215, 215, 215), stop:1 rgb(222, 222, 222)); + border-width: 1px; + border-radius: 5px; + color: #808086; + padding: 2px; + background-color: rgb(142,142,142); +} +QLineEdit { + border-width: 1px; border-radius: 4px; + border-style: solid; + border-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(0, 113, 255, 255), stop:1 rgba(91, 171, 252, 255)); +} +QLabel { + color: #000000; +} +QLCDNumber { + color: rgb(0, 113, 255, 255); +} +QProgressBar { + text-align: center; + color: rgb(240, 240, 240); + border-width: 1px; + border-radius: 10px; + border-color: rgb(230, 230, 230); + border-style: solid; + background-color:rgb(207,207,207); +} +QProgressBar::chunk { + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(49, 147, 250, 255), stop:1 rgba(34, 142, 255, 255)); + border-radius: 10px; +} +QMenuBar { + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(207, 209, 207, 255), stop:1 rgba(230, 229, 230, 255)); +} +QMenuBar::item { + color: #000000; + spacing: 3px; + padding: 1px 4px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(207, 209, 207, 255), stop:1 rgba(230, 229, 230, 255)); +} + +QMenuBar::item:selected { + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(0, 113, 255, 255), stop:1 rgba(91, 171, 252, 255)); + color: #FFFFFF; +} +QMenu::item:selected { + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(0, 113, 255, 255), stop:1 rgba(91, 171, 252, 255)); + border-bottom-color: transparent; + border-left-width: 2px; + color: #000000; + padding-left:15px; + padding-top:4px; + padding-bottom:4px; + padding-right:7px; +} +QMenu::item { + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: transparent; + border-bottom-width: 1px; + color: #000000; + padding-left:17px; + padding-top:4px; + padding-bottom:4px; + padding-right:7px; +} +QTabWidget { + color:rgb(0,0,0); + background-color:#000000; +} +QTabWidget::pane { + border-color: rgb(223,223,223); + background-color:rgb(226,226,226); + border-style: solid; + border-width: 2px; + border-radius: 6px; +} +QTabBar::tab:first { + border-style: solid; + border-left-width:1px; + border-right-width:0px; + border-top-width:1px; + border-bottom-width:1px; + border-top-color: rgb(209,209,209); + border-left-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(209, 209, 209, 209), stop:1 rgba(229, 229, 229, 229)); + border-bottom-color: rgb(229,229,229); + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + color: #000000; + padding: 3px; + margin-left:0px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(247, 247, 247, 255), stop:1 rgba(255, 255, 255, 255)); +} +QTabBar::tab:last { + border-style: solid; + border-width:1px; + border-top-color: rgb(209,209,209); + border-left-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(209, 209, 209, 209), stop:1 rgba(229, 229, 229, 229)); + border-right-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(209, 209, 209, 209), stop:1 rgba(229, 229, 229, 229)); + border-bottom-color: rgb(229,229,229); + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + color: #000000; + padding: 3px; + margin-left:0px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(247, 247, 247, 255), stop:1 rgba(255, 255, 255, 255)); +} +QTabBar::tab { + border-style: solid; + border-top-width:1px; + border-bottom-width:1px; + border-left-width:1px; + border-top-color: rgb(209,209,209); + border-left-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(209, 209, 209, 209), stop:1 rgba(229, 229, 229, 229)); + border-bottom-color: rgb(229,229,229); + color: #000000; + padding: 3px; + margin-left:0px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(247, 247, 247, 255), stop:1 rgba(255, 255, 255, 255)); +} +QTabBar::tab:selected, QTabBar::tab:last:selected, QTabBar::tab:hover { + border-style: solid; + border-left-width:1px; + border-right-color: transparent; + border-top-color: rgb(209,209,209); + border-left-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(209, 209, 209, 209), stop:1 rgba(229, 229, 229, 229)); + border-bottom-color: rgb(229,229,229); + color: #FFFFFF; + padding: 3px; + margin-left:0px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(0, 113, 255, 255), stop:1 rgba(91, 171, 252, 255)); +} + +QTabBar::tab:selected, QTabBar::tab:first:selected, QTabBar::tab:hover { + border-style: solid; + border-left-width:1px; + border-bottom-width:1px; + border-top-width:1px; + border-right-color: transparent; + border-top-color: rgb(209,209,209); + border-left-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(209, 209, 209, 209), stop:1 rgba(229, 229, 229, 229)); + border-bottom-color: rgb(229,229,229); + color: #FFFFFF; + padding: 3px; + margin-left:0px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(0, 113, 255, 255), stop:1 rgba(91, 171, 252, 255)); +} + +QCheckBox { + color: #000000; + padding: 2px; +} +QCheckBox:disabled { + color: #808086; + padding: 2px; +} + +QCheckBox:hover { + border-radius:4px; + border-style:solid; + padding-left: 1px; + padding-right: 1px; + padding-bottom: 1px; + padding-top: 1px; + border-width:1px; + border-color: transparent; +} +QCheckBox::indicator:checked { + + height: 10px; + width: 10px; + border-style:solid; + border-width: 1px; + border-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(0, 113, 255, 255), stop:1 rgba(91, 171, 252, 255)); + color: #000000; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(0, 113, 255, 255), stop:1 rgba(91, 171, 252, 255)); +} +QCheckBox::indicator:unchecked { + + height: 10px; + width: 10px; + border-style:solid; + border-width: 1px; + border-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(0, 113, 255, 255), stop:1 rgba(91, 171, 252, 255)); + color: #000000; +} +QRadioButton { + color: 000000; + padding: 1px; +} +QRadioButton::indicator:checked { + height: 10px; + width: 10px; + border-style:solid; + border-radius:5px; + border-width: 1px; + border-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(0, 113, 255, 255), stop:1 rgba(91, 171, 252, 255)); + color: #a9b7c6; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(0, 113, 255, 255), stop:1 rgba(91, 171, 252, 255)); +} +QRadioButton::indicator:!checked { + height: 10px; + width: 10px; + border-style:solid; + border-radius:5px; + border-width: 1px; + border-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(0, 113, 255, 255), stop:1 rgba(91, 171, 252, 255)); + color: #a9b7c6; + background-color: transparent; +} +QStatusBar { + color:#027f7f; +} +QSpinBox { + border-style: solid; + border-width: 1px; + border-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(0, 113, 255, 255), stop:1 rgba(91, 171, 252, 255)); +} +QDoubleSpinBox { + border-style: solid; + border-width: 1px; + border-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(0, 113, 255, 255), stop:1 rgba(91, 171, 252, 255)); +} +QTimeEdit { + border-style: solid; + border-width: 1px; + border-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(0, 113, 255, 255), stop:1 rgba(91, 171, 252, 255)); +} +QDateTimeEdit { + border-style: solid; + border-width: 1px; + border-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(0, 113, 255, 255), stop:1 rgba(91, 171, 252, 255)); +} +QDateEdit { + border-style: solid; + border-width: 1px; + border-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(0, 113, 255, 255), stop:1 rgba(91, 171, 252, 255)); +} + +QToolBox { + color: #a9b7c6; + background-color:#000000; +} +QToolBox::tab { + color: #a9b7c6; + background-color:#000000; +} +QToolBox::tab:selected { + color: #FFFFFF; + background-color:#000000; +} +QScrollArea { + color: #FFFFFF; + background-color:#000000; +} +QSlider::groove:horizontal { + height: 5px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(49, 147, 250, 255), stop:1 rgba(34, 142, 255, 255)); +} +QSlider::groove:vertical { + width: 5px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(49, 147, 250, 255), stop:1 rgba(34, 142, 255, 255)); +} +QSlider::handle:horizontal { + background: rgb(253,253,253); + border-style: solid; + border-width: 1px; + border-color: rgb(207,207,207); + width: 12px; + margin: -5px 0; + border-radius: 7px; +} +QSlider::handle:vertical { + background: rgb(253,253,253); + border-style: solid; + border-width: 1px; + border-color: rgb(207,207,207); + height: 12px; + margin: 0 -5px; + border-radius: 7px; +} +QSlider::add-page:horizontal { + background: rgb(181,181,181); +} +QSlider::add-page:vertical { + background: rgb(181,181,181); +} +QSlider::sub-page:horizontal { + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(49, 147, 250, 255), stop:1 rgba(34, 142, 255, 255)); +} +QSlider::sub-page:vertical { + background-color: qlineargradient(spread:pad, y1:0.5, x1:1, y2:0.5, x2:0, stop:0 rgba(49, 147, 250, 255), stop:1 rgba(34, 142, 255, 255)); +} +QScrollBar:horizontal { + max-height: 20px; + border: 1px transparent grey; + margin: 0px 20px 0px 20px; +} +QScrollBar:vertical { + max-width: 20px; + border: 1px transparent grey; + margin: 20px 0px 20px 0px; +} +QScrollBar::handle:horizontal { + background: rgb(253,253,253); + border-style: solid; + border-width: 1px; + border-color: rgb(207,207,207); + border-radius: 7px; + min-width: 25px; +} +QScrollBar::handle:horizontal:hover { + background: rgb(253,253,253); + border-style: solid; + border-width: 1px; + border-color: rgb(147, 200, 200); + border-radius: 7px; + min-width: 25px; +} +QScrollBar::handle:vertical { + background: rgb(253,253,253); + border-style: solid; + border-width: 1px; + border-color: rgb(207,207,207); + border-radius: 7px; + min-height: 25px; +} +QScrollBar::handle:vertical:hover { + background: rgb(253,253,253); + border-style: solid; + border-width: 1px; + border-color: rgb(147, 200, 200); + border-radius: 7px; + min-height: 25px; +} +QScrollBar::add-line:horizontal { + border: 2px transparent grey; + border-top-right-radius: 7px; + border-bottom-right-radius: 7px; + background: rgba(34, 142, 255, 255); + width: 20px; + subcontrol-position: right; + subcontrol-origin: margin; +} +QScrollBar::add-line:horizontal:pressed { + border: 2px transparent grey; + border-top-right-radius: 7px; + border-bottom-right-radius: 7px; + background: rgb(181,181,181); + width: 20px; + subcontrol-position: right; + subcontrol-origin: margin; +} +QScrollBar::add-line:vertical { + border: 2px transparent grey; + border-bottom-left-radius: 7px; + border-bottom-right-radius: 7px; + background: rgba(34, 142, 255, 255); + height: 20px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} +QScrollBar::add-line:vertical:pressed { + border: 2px transparent grey; + border-bottom-left-radius: 7px; + border-bottom-right-radius: 7px; + background: rgb(181,181,181); + height: 20px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} +QScrollBar::sub-line:horizontal { + border: 2px transparent grey; + border-top-left-radius: 7px; + border-bottom-left-radius: 7px; + background: rgba(34, 142, 255, 255); + width: 20px; + subcontrol-position: left; + subcontrol-origin: margin; +} +QScrollBar::sub-line:horizontal:pressed { + border: 2px transparent grey; + border-top-left-radius: 7px; + border-bottom-left-radius: 7px; + background: rgb(181,181,181); + width: 20px; + subcontrol-position: left; + subcontrol-origin: margin; +} +QScrollBar::sub-line:vertical { + border: 2px transparent grey; + border-top-left-radius: 7px; + border-top-right-radius: 7px; + background: rgba(34, 142, 255, 255); + height: 20px; + subcontrol-position: top; + subcontrol-origin: margin; +} +QScrollBar::sub-line:vertical:pressed { + border: 2px transparent grey; + border-top-left-radius: 7px; + border-top-right-radius: 7px; + background: rgb(181,181,181); + height: 20px; + subcontrol-position: top; + subcontrol-origin: margin; +} +QScrollBar::left-arrow:horizontal { + border: 1px transparent grey; + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; + width: 6px; + height: 6px; + background: white; +} +QScrollBar::right-arrow:horizontal { + border: 1px transparent grey; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + width: 6px; + height: 6px; + background: white; +} +QScrollBar::up-arrow:vertical { + border: 1px transparent grey; + border-top-left-radius: 3px; + border-top-right-radius: 3px; + width: 6px; + height: 6px; + background: white; +} +QScrollBar::down-arrow:vertical { + border: 1px transparent grey; + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; + width: 6px; + height: 6px; + background: white; +} +QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal { + background: none; +} +QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + background: none; +} diff --git a/module/radio/styles/qss/ConsoleStyle.qss b/module/radio/styles/qss/ConsoleStyle.qss new file mode 100644 index 0000000..af6c204 --- /dev/null +++ b/module/radio/styles/qss/ConsoleStyle.qss @@ -0,0 +1,181 @@ +/* +Dark Console Style Sheet for QT Applications +Author: Jaime A. Quiroga P. +Company: GTRONICK +Last updated: 24/05/2018, 17:12. +Available at: https://github.com/GTRONICK/QSS/blob/master/ConsoleStyle.qss +*/ +QWidget { + background-color:rgb(0, 0, 0); + color: rgb(240, 240, 240); + border-color: rgb(58, 58, 58); +} + +QPlainTextEdit { + background-color:rgb(0, 0, 0); + color: rgb(200, 200, 200); + selection-background-color: rgb(255, 153, 0); + selection-color: rgb(0, 0, 0); +} + +QTabWidget::pane { + border-top: 1px solid #000000; +} + +QTabBar::tab { + background-color:rgb(0, 0, 0); + border-style: outset; + border-width: 1px; + border-right-color: qlineargradient(spread:pad, x1:0.4, y1:0.5, x2:0.6, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-left-color: qlineargradient(spread:pad, x1:0.6, y1:0.5, x2:0.4, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-bottom-color: rgb(58, 58, 58); + border-bottom-width: 1px; + border-top-width: 0px; + border-style: solid; + color: rgb(255, 153, 0); + padding: 4px; +} + +QTabBar::tab:selected, QTabBar::tab:hover { + color: rgb(255, 255, 255); + background-color:rgb(0, 0, 0); + border-color:rgb(42, 42, 42); + margin-left: 0px; + margin-right: 0px; + border-bottom-right-radius:4px; + border-bottom-left-radius:4px; +} + +QTabBar::tab:last:selected { + background-color:rgb(0, 0, 0); + border-color:rgb(42, 42, 42); + margin-left: 0px; + margin-right: 0px; + border-bottom-right-radius:4px; + border-bottom-left-radius:4px; +} + +QTabBar::tab:!selected { + margin-bottom: 4px; + border-bottom-right-radius:4px; + border-bottom-left-radius:4px; +} + +QPushButton{ + border-style: outset; + border-width: 2px; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:0.6, x2:0.5, y2:0.4, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-right-color: qlineargradient(spread:pad, x1:0.4, y1:0.5, x2:0.6, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-left-color: qlineargradient(spread:pad, x1:0.6, y1:0.5, x2:0.4, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-bottom-color: rgb(58, 58, 58); + border-bottom-width: 1px; + border-style: solid; + color: rgb(255, 255, 255); + padding: 6px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(77, 77, 77, 255), stop:1 rgba(97, 97, 97, 255)); +} + +QPushButton:hover{ + border-style: outset; + border-width: 2px; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:0.6, x2:0.5, y2:0.4, stop:0 rgba(180, 180, 180, 255), stop:1 rgba(110, 110, 110, 255)); + border-right-color: qlineargradient(spread:pad, x1:0.4, y1:0.5, x2:0.6, y2:0.5, stop:0 rgba(180, 180, 180, 255), stop:1 rgba(110, 110, 110, 255)); + border-left-color: qlineargradient(spread:pad, x1:0.6, y1:0.5, x2:0.4, y2:0.5, stop:0 rgba(180, 180, 180, 255), stop:1 rgba(110, 110, 110, 255)); + border-bottom-color: rgb(115, 115, 115); + border-bottom-width: 1px; + border-style: solid; + color: rgb(255, 255, 255); + padding: 6px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(107, 107, 107, 255), stop:1 rgba(157, 157, 157, 255)); +} + +QPushButton:pressed{ + border-style: outset; + border-width: 2px; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:0.6, x2:0.5, y2:0.4, stop:0 rgba(62, 62, 62, 255), stop:1 rgba(22, 22, 22, 255)); + border-right-color: qlineargradient(spread:pad, x1:0.4, y1:0.5, x2:0.6, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-left-color: qlineargradient(spread:pad, x1:0.6, y1:0.5, x2:0.4, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-bottom-color: rgb(58, 58, 58); + border-bottom-width: 1px; + border-style: solid; + color: rgb(255, 255, 255); + padding: 6px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(77, 77, 77, 255), stop:1 rgba(97, 97, 97, 255)); +} + +QPushButton:disabled{ + border-style: outset; + border-width: 2px; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:0.6, x2:0.5, y2:0.4, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-right-color: qlineargradient(spread:pad, x1:0.4, y1:0.5, x2:0.6, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-left-color: qlineargradient(spread:pad, x1:0.6, y1:0.5, x2:0.4, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-bottom-color: rgb(58, 58, 58); + border-bottom-width: 1px; + border-style: solid; + color: rgb(0, 0, 0); + padding: 6px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(57, 57, 57, 255), stop:1 rgba(77, 77, 77, 255)); +} + +QLineEdit { + border-width: 1px; border-radius: 4px; + border-color: rgb(58, 58, 58); + border-style: inset; + padding: 0 8px; + color: rgb(255, 255, 255); + background:rgb(101, 101, 101); + selection-background-color: rgb(187, 187, 187); + selection-color: rgb(60, 63, 65); +} + +QProgressBar { + text-align: center; + color: rgb(255, 255, 255); + border-width: 1px; + border-radius: 10px; + border-color: rgb(58, 58, 58); + border-style: inset; +} + +QProgressBar::chunk { + background-color: qlineargradient(spread:pad, x1:0.5, y1:0.7, x2:0.5, y2:0.3, stop:0 rgba(0, 200, 0, 255), stop:1 rgba(30, 230, 30, 255)); + border-radius: 10px; +} + +QMenuBar { + background:rgb(0, 0, 0); + color: rgb(255, 153, 0); +} + +QMenuBar::item { + spacing: 3px; + padding: 1px 4px; + background: transparent; +} + +QMenuBar::item:selected { + background:rgb(115, 115, 115); +} + +QMenu { + border-width: 2px; + border-radius: 10px; + border-color: rgb(255, 153, 0); + border-style: outset; +} + +QMenu::item { + spacing: 3px; + padding: 3px 15px; +} + +QMenu::item:selected { + spacing: 3px; + padding: 3px 15px; + background:rgb(115, 115, 115); + color:rgb(255, 255, 255); + border-width: 1px; + border-radius: 10px; + border-color: rgb(58, 58, 58); + border-style: inset; +} diff --git a/module/radio/styles/qss/ElegantDark.qss b/module/radio/styles/qss/ElegantDark.qss new file mode 100644 index 0000000..abe1770 --- /dev/null +++ b/module/radio/styles/qss/ElegantDark.qss @@ -0,0 +1,231 @@ +/* +ElegantDark Style Sheet for QT Applications +Author: Jaime A. Quiroga P. +Company: GTRONICK +Last updated: 17/04/2018 +Available at: https://github.com/GTRONICK/QSS/blob/master/ElegantDark.qss +*/ +QMainWindow { + background-color:rgb(82, 82, 82); +} +QTextEdit { + background-color:rgb(42, 42, 42); + color: rgb(0, 255, 0); +} +/* +QPushButton{ + border-style: outset; + border-width: 2px; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:0.6, x2:0.5, y2:0.4, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-right-color: qlineargradient(spread:pad, x1:0.4, y1:0.5, x2:0.6, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-left-color: qlineargradient(spread:pad, x1:0.6, y1:0.5, x2:0.4, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-bottom-color: rgb(58, 58, 58); + border-bottom-width: 1px; + border-style: solid; + color: rgb(0, 0, 0); + padding: 2px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(57, 57, 57, 255), stop:1 rgba(77, 77, 77, 255)); +} +*/ +QPushButton{ + border-style: outset; + border-width: 2px; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:0.6, x2:0.5, y2:0.4, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-right-color: qlineargradient(spread:pad, x1:0.4, y1:0.5, x2:0.6, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-left-color: qlineargradient(spread:pad, x1:0.6, y1:0.5, x2:0.4, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-bottom-color: rgb(58, 58, 58); + border-bottom-width: 1px; + border-style: solid; + color: rgb(255, 255, 255); + padding: 2px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(77, 77, 77, 255), stop:1 rgba(97, 97, 97, 255)); +} +QPushButton:hover{ + border-style: outset; + border-width: 2px; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:0.6, x2:0.5, y2:0.4, stop:0 rgba(180, 180, 180, 255), stop:1 rgba(110, 110, 110, 255)); + border-right-color: qlineargradient(spread:pad, x1:0.4, y1:0.5, x2:0.6, y2:0.5, stop:0 rgba(180, 180, 180, 255), stop:1 rgba(110, 110, 110, 255)); + border-left-color: qlineargradient(spread:pad, x1:0.6, y1:0.5, x2:0.4, y2:0.5, stop:0 rgba(180, 180, 180, 255), stop:1 rgba(110, 110, 110, 255)); + border-bottom-color: rgb(115, 115, 115); + border-bottom-width: 1px; + border-style: solid; + color: rgb(255, 255, 255); + padding: 2px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(107, 107, 107, 255), stop:1 rgba(157, 157, 157, 255)); +} +QPushButton:pressed{ + border-style: outset; + border-width: 2px; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:0.6, x2:0.5, y2:0.4, stop:0 rgba(62, 62, 62, 255), stop:1 rgba(22, 22, 22, 255)); + border-right-color: qlineargradient(spread:pad, x1:0.4, y1:0.5, x2:0.6, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-left-color: qlineargradient(spread:pad, x1:0.6, y1:0.5, x2:0.4, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-bottom-color: rgb(58, 58, 58); + border-bottom-width: 1px; + border-style: solid; + color: rgb(255, 255, 255); + padding: 2px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(77, 77, 77, 255), stop:1 rgba(97, 97, 97, 255)); +} +QPushButton:disabled{ + border-style: outset; + border-width: 2px; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:0.6, x2:0.5, y2:0.4, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-right-color: qlineargradient(spread:pad, x1:0.4, y1:0.5, x2:0.6, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-left-color: qlineargradient(spread:pad, x1:0.6, y1:0.5, x2:0.4, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-bottom-color: rgb(58, 58, 58); + border-bottom-width: 1px; + border-style: solid; + color: rgb(255, 255, 255); + padding: 2px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(77, 77, 77, 255), stop:1 rgba(97, 97, 97, 255)); +} + +QPushButton:checked { + border-style: outset; + border-width: 2px; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:0.6, x2:0.5, y2:0.4, stop:0 rgba(62, 62, 62, 255), stop:1 rgba(22, 22, 22, 255)); + border-right-color: qlineargradient(spread:pad, x1:0.4, y1:0.5, x2:0.6, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-left-color: qlineargradient(spread:pad, x1:0.6, y1:0.5, x2:0.4, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-bottom-color: rgb(58, 58, 58); + border-bottom-width: 1px; + border-style: solid; + color: rgb(255, 0, 0); + padding: 2px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(197, 197, 197, 255), stop:1 rgba(177, 177, 177, 255)); +} + + + +QLineEdit { + border-width: 1px; border-radius: 4px; + border-color: rgb(58, 58, 58); + border-style: inset; + padding: 0 8px; + color: rgb(255, 255, 255); + background:rgb(100, 100, 100); + selection-background-color: rgb(187, 187, 187); + selection-color: rgb(60, 63, 65); +} + +/* +QLabel { + color:rgb(255,255,255); +} +*/ +QProgressBar { + text-align: center; + color: rgb(240, 240, 240); + border-width: 1px; + border-radius: 10px; + border-color: rgb(58, 58, 58); + border-style: inset; + background-color:rgb(77,77,77); +} +QProgressBar::chunk { + background-color: qlineargradient(spread:pad, x1:0.5, y1:0.7, x2:0.5, y2:0.3, stop:0 rgba(87, 97, 106, 255), stop:1 rgba(93, 103, 113, 255)); + border-radius: 5px; +} +QMenuBar { + background:rgb(82, 82, 82); +} +QMenuBar::item { + color:rgb(223,219,210); + spacing: 3px; + padding: 1px 4px; + background: transparent; +} + +QMenuBar::item:selected { + background:rgb(115, 115, 115); +} +QMenu::item:selected { + color:rgb(255,255,255); + border-width:2px; + border-style:solid; + padding-left:18px; + padding-right:8px; + padding-top:2px; + padding-bottom:3px; + background:qlineargradient(spread:pad, x1:0.5, y1:0.7, x2:0.5, y2:0.3, stop:0 rgba(87, 97, 106, 255), stop:1 rgba(93, 103, 113, 255)); + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:0.6, x2:0.5, y2:0.4, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-right-color: qlineargradient(spread:pad, x1:0.4, y1:0.5, x2:0.6, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-left-color: qlineargradient(spread:pad, x1:0.6, y1:0.5, x2:0.4, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(62, 62, 62, 255)); + border-bottom-color: rgb(58, 58, 58); + border-bottom-width: 1px; +} +QMenu::item { + color:rgb(223,219,210); + background-color:rgb(78,78,78); + padding-left:20px; + padding-top:4px; + padding-bottom:4px; + padding-right:10px; +} +QMenu{ + background-color:rgb(78,78,78); +} +QTabWidget { + color:rgb(0,0,0); + background-color:rgb(247,246,246); +} +QTabWidget::pane { + border-color: rgb(77,77,77); + background-color:rgb(101,101,101); + border-style: solid; + border-width: 1px; + border-radius: 6px; +} +QTabBar::tab { + padding:2px; + color:rgb(250,250,250); + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(77, 77, 77, 255), stop:1 rgba(97, 97, 97, 255)); + border-style: solid; + border-width: 2px; + border-top-right-radius:4px; + border-top-left-radius:4px; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:0.6, x2:0.5, y2:0.4, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(95, 92, 93, 255)); + border-right-color: qlineargradient(spread:pad, x1:0.4, y1:0.5, x2:0.6, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(95, 92, 93, 255)); + border-left-color: qlineargradient(spread:pad, x1:0.6, y1:0.5, x2:0.4, y2:0.5, stop:0 rgba(115, 115, 115, 255), stop:1 rgba(95, 92, 93, 255)); + border-bottom-color: rgb(101,101,101); +} +QTabBar::tab:selected, QTabBar::tab:last:selected, QTabBar::tab:hover { + background-color:rgb(101,101,101); + margin-left: 0px; + margin-right: 1px; +} +QTabBar::tab:!selected { + margin-top: 1px; + margin-right: 1px; +} +QCheckBox { + color:rgb(223,219,210); + padding: 2px; +} +QCheckBox:hover { + border-radius:4px; + border-style:solid; + padding-left: 1px; + padding-right: 1px; + padding-bottom: 1px; + padding-top: 1px; + border-width:1px; + border-color: rgb(87, 97, 106); + background-color:qlineargradient(spread:pad, x1:0.5, y1:0.7, x2:0.5, y2:0.3, stop:0 rgba(87, 97, 106, 150), stop:1 rgba(93, 103, 113, 150)); +} +QCheckBox::indicator:checked { + border-radius:4px; + border-style:solid; + border-width:1px; + border-color: rgb(180,180,180); + background-color:qlineargradient(spread:pad, x1:0.5, y1:0.7, x2:0.5, y2:0.3, stop:0 rgba(87, 97, 106, 255), stop:1 rgba(93, 103, 113, 255)); +} +QCheckBox::indicator:unchecked { + border-radius:4px; + border-style:solid; + border-width:1px; + border-color: rgb(87, 97, 106); + background-color:rgb(255,255,255); +} +QStatusBar { + color:rgb(240,240,240); +} diff --git a/module/radio/styles/qss/LICENSE b/module/radio/styles/qss/LICENSE new file mode 100644 index 0000000..868ac31 --- /dev/null +++ b/module/radio/styles/qss/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Jaime Quiroga + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/module/radio/styles/qss/MacOS.qss b/module/radio/styles/qss/MacOS.qss new file mode 100644 index 0000000..9a98622 --- /dev/null +++ b/module/radio/styles/qss/MacOS.qss @@ -0,0 +1,434 @@ +/* + * MacOS Style Sheet for QT Applications + * Author: Jaime A. Quiroga P. + * Company: GTRONICK + * Last updated: 25/12/2020, 23:10. + * Available at: https://github.com/GTRONICK/QSS/blob/master/MacOS.qss + */ +QMainWindow { + background-color:#ececec; +} +QPushButton, QToolButton, QCommandLinkButton{ + padding: 0 5px 0 5px; + border-style: solid; + border-top-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #c1c9cf, stop:1 #d2d8dd); + border-right-color: qlineargradient(spread:pad, x1:1, y1:0, x2:0, y2:0, stop:0 #c1c9cf, stop:1 #d2d8dd); + border-bottom-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 #c1c9cf, stop:1 #d2d8dd); + border-left-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #c1c9cf, stop:1 #d2d8dd); + border-width: 2px; + border-radius: 8px; + color: #616161; + font-weight: bold; + background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 #fbfdfd, stop:0.5 #ffffff, stop:1 #fbfdfd); +} +QPushButton::default, QToolButton::default, QCommandLinkButton::default{ + border: 2px solid transparent; + color: #FFFFFF; + background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 #84afe5, stop:1 #1168e4); +} +QPushButton:hover, QToolButton:hover, QCommandLinkButton:hover{ + color: #3d3d3d; +} +QPushButton:pressed, QToolButton:pressed, QCommandLinkButton:pressed{ + color: #aeaeae; + background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 #ffffff, stop:0.5 #fbfdfd, stop:1 #ffffff); +} +QPushButton:disabled, QToolButton:disabled, QCommandLinkButton:disabled{ + color: #616161; + background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 #dce7eb, stop:0.5 #e0e8eb, stop:1 #dee7ec); +} +QLineEdit, QTextEdit, QPlainTextEdit, QSpinBox, QDoubleSpinBox, QTimeEdit, QDateEdit, QDateTimeEdit { + border-width: 2px; + border-radius: 8px; + border-style: solid; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 #c1c9cf, stop:1 #d2d8dd); + border-right-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #c1c9cf, stop:1 #d2d8dd); + border-bottom-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 #c1c9cf, stop:1 #d2d8dd); + border-left-color: qlineargradient(spread:pad, x1:1, y1:0, x2:0, y2:0, stop:0 #c1c9cf, stop:1 #d2d8dd); + background-color: #f4f4f4; + color: #3d3d3d; +} +QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus, QSpinBox:focus, QDoubleSpinBox:focus, QTimeEdit:focus, QDateEdit:focus, QDateTimeEdit:focus { + border-width: 2px; + border-radius: 8px; + border-style: solid; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 #85b7e3, stop:1 #9ec1db); + border-right-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #85b7e3, stop:1 #9ec1db); + border-bottom-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 #85b7e3, stop:1 #9ec1db); + border-left-color: qlineargradient(spread:pad, x1:1, y1:0, x2:0, y2:0, stop:0 #85b7e3, stop:1 #9ec1db); + background-color: #f4f4f4; + color: #3d3d3d; +} +QLineEdit:disabled, QTextEdit:disabled, QPlainTextEdit:disabled, QSpinBox:disabled, QDoubleSpinBox:disabled, QTimeEdit:disabled, QDateEdit:disabled, QDateTimeEdit:disabled { + color: #b9b9b9; +} +QSpinBox::up-button, QDoubleSpinBox::up-button, QTimeEdit::up-button, QDateEdit::up-button, QDateTimeEdit::up-button { + subcontrol-origin: padding; + subcontrol-position: top right; + width: 15px; + color: #272727; + border-left-width: 1px; + border-left-color: darkgray; + border-left-style: solid; + border-top-right-radius: 3px; + padding: 3px; +} +QSpinBox::down-button, QDoubleSpinBox::down-button, QTimeEdit::down-button, QDateEdit::down-button, QDateTimeEdit::down-button { + subcontrol-origin: padding; + subcontrol-position: bottom right; + width: 15px; + color: #272727; + border-left-width: 1px; + border-left-color: darkgray; + border-left-style: solid; + border-bottom-right-radius: 3px; + padding: 3px; +} +QSpinBox::up-button:pressed, QDoubleSpinBox::up-button:pressed, QTimeEdit::up-button:pressed, QDateEdit::up-button:pressed, QDateTimeEdit::up-button:pressed { + color: #aeaeae; + background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 #ffffff, stop:0.5 #fbfdfd, stop:1 #ffffff); +} +QSpinBox::down-button:pressed, QDoubleSpinBox::down-button:pressed, QTimeEdit::down-button:pressed, QDateEdit::down-button:pressed, QDateTimeEdit::down-button:pressed { + color: #aeaeae; + background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 #ffffff, stop:0.5 #fbfdfd, stop:1 #ffffff); +} +QSpinBox::up-button:hover, QDoubleSpinBox::up-button:hover, QTimeEdit::up-button:hover, QDateEdit::up-button:hover, QDateTimeEdit::up-button:hover { + color: #FFFFFF; + border-top-right-radius: 5px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 #84afe5, stop:1 #1168e4); + +} +QSpinBox::down-button:hover, QDoubleSpinBox::down-button:hover, QTimeEdit::down-button:hover, QDateEdit::down-button:hover, QDateTimeEdit::down-button:hover { + color: #FFFFFF; + border-bottom-right-radius: 5px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 #84afe5, stop:1 #1168e4); +} +QSpinBox::up-arrow, QDoubleSpinBox::up-arrow, QTimeEdit::up-arrow, QDateEdit::up-arrow, QDateTimeEdit::up-arrow { + image: url(/usr/share/icons/Adwaita/16x16/actions/go-up-symbolic.symbolic.png); +} +QSpinBox::down-arrow, QDoubleSpinBox::down-arrow, QTimeEdit::down-arrow, QDateEdit::down-arrow, QDateTimeEdit::down-arrow { + image: url(/usr/share/icons/Adwaita/16x16/actions/go-down-symbolic.symbolic.png); +} +QProgressBar { + max-height: 8px; + text-align: center; + font: italic bold 11px; + color: #3d3d3d; + border: 1px solid transparent; + border-radius:4px; + background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #ddd5d5, stop:0.5 #dad3d3, stop:1 #ddd5d5); +} +QProgressBar::chunk { + background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #467dd1, stop:0.5 #3b88fc, stop:1 #467dd1); + border-radius: 4px; +} +QProgressBar:disabled { + color: #616161; +} +QProgressBar::chunk:disabled { + background-color: #aeaeae; +} +QSlider::groove { + border: 1px solid #bbbbbb; + background-color: #52595d; + border-radius: 4px; +} +QSlider::groove:horizontal { + height: 6px; +} +QSlider::groove:vertical { + width: 6px; +} +QSlider::handle:horizontal { + background: #ffffff; + border-style: solid; + border-width: 1px; + border-color: rgb(207,207,207); + width: 12px; + margin: -5px 0; + border-radius: 7px; +} +QSlider::handle:vertical { + background: #ffffff; + border-style: solid; + border-width: 1px; + border-color: rgb(207,207,207); + height: 12px; + margin: 0 -5px; + border-radius: 7px; +} +QSlider::add-page, QSlider::sub-page { + border: 1px transparent; + background-color: #52595d; + border-radius: 4px; +} +QSlider::add-page:horizontal { + background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #ddd5d5, stop:0.5 #dad3d3, stop:1 #ddd5d5); +} +QSlider::sub-page:horizontal { + background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #467dd1, stop:0.5 #3b88fc, stop:1 #467dd1); +} +QSlider::add-page:vertical { + background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #467dd1, stop:0.5 #3b88fc, stop:1 #467dd1); +} +QSlider::sub-page:vertical { + background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #ddd5d5, stop:0.5 #dad3d3, stop:1 #ddd5d5); +} +QSlider::add-page:horizontal:disabled, QSlider::sub-page:horizontal:disabled, QSlider::add-page:vertical:disabled, QSlider::sub-page:vertical:disabled { + background: #b9b9b9; +} +QComboBox, QFontComboBox { + border-width: 2px; + border-radius: 8px; + border-style: solid; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 #c1c9cf, stop:1 #d2d8dd); + border-right-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #c1c9cf, stop:1 #d2d8dd); + border-bottom-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 #c1c9cf, stop:1 #d2d8dd); + border-left-color: qlineargradient(spread:pad, x1:1, y1:0, x2:0, y2:0, stop:0 #c1c9cf, stop:1 #d2d8dd); + background-color: #f4f4f4; + color: #272727; + padding-left: 5px; +} +QComboBox:editable, QComboBox:!editable, QComboBox::drop-down:editable, QComboBox:!editable:on, QComboBox::drop-down:editable:on { + background: #ffffff; +} +QComboBox::drop-down { + subcontrol-origin: padding; + subcontrol-position: top right; + width: 15px; + color: #272727; + border-left-width: 1px; + border-left-color: darkgray; + border-left-style: solid; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} +QComboBox::down-arrow { + image: url(/usr/share/icons/Adwaita/16x16/actions/go-down-symbolic.symbolic.png); /*Adawaita icon thene*/ +} + +QComboBox::down-arrow:on { + top: 1px; + left: 1px; +} +QComboBox QAbstractItemView { + border: 1px solid darkgray; + border-radius: 8px; + selection-background-color: #dadada; + selection-color: #272727; + color: #272727; + background: white; +} +QLabel, QCheckBox, QRadioButton { + color: #272727; +} +QCheckBox { + padding: 2px; +} +QCheckBox:disabled, QRadioButton:disabled { + color: #808086; + padding: 2px; +} + +QCheckBox:hover { + border-radius:4px; + border-style:solid; + padding-left: 1px; + padding-right: 1px; + padding-bottom: 1px; + padding-top: 1px; + border-width:1px; + border-color: transparent; +} +QCheckBox::indicator:checked { + image: url(/usr/share/icons/Adwaita/16x16/actions/object-select-symbolic.symbolic.png); + height: 15px; + width: 15px; + border-style:solid; + border-width: 1px; + border-color: #48a5fd; + color: #ffffff; + border-radius: 3px; + background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #48a5fd, stop:0.5 #329cfb, stop:1 #48a5fd); +} +QCheckBox::indicator:unchecked { + + height: 15px; + width: 15px; + border-style:solid; + border-width: 1px; + border-color: #48a5fd; + border-radius: 3px; + background-color: #fbfdfa; +} +QLCDNumber { + color: #616161;; +} +QMenuBar { + background-color: #ececec; +} +QMenuBar::item { + color: #616161; + spacing: 3px; + padding: 1px 4px; + background-color: #ececec; +} + +QMenuBar::item:selected { + background-color: #dadada; + color: #3d3d3d; +} +QMenu { + background-color: #ececec; +} +QMenu::item:selected { + background-color: #dadada; + color: #3d3d3d; +} +QMenu::item { + color: #616161;; + background-color: #e0e0e0; +} +QTabWidget { + color:rgb(0,0,0); + background-color:#000000; +} +QTabWidget::pane { + border-color: #050a0e; + background-color: #e0e0e0; + border-width: 1px; + border-radius: 4px; + position: absolute; + top: -0.5em; + padding-top: 0.5em; +} + +QTabWidget::tab-bar { + alignment: center; +} + +QTabBar::tab { + border-bottom: 1px solid #c0c0c0; + padding: 3px; + color: #272727; + background-color: #fefefc; + margin-left:0px; +} +QTabBar::tab:!last { + border-right: 1px solid; + border-right-color: #c0c0c0; + border-bottom-color: #c0c0c0; +} +QTabBar::tab:first { + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} +QTabBar::tab:last { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} +QTabBar::tab:selected, QTabBar::tab:last:selected, QTabBar::tab:hover { + color: #FFFFFF; + background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 #84afe5, stop:1 #1168e4); +} +QRadioButton::indicator { + height: 14px; + width: 14px; + border-style:solid; + border-radius:7px; + border-width: 1px; +} +QRadioButton::indicator:checked { + border-color: #48a5fd; + background-color: qradialgradient(cx:0.5, cy:0.5, radius:0.4,fx:0.5, fy:0.5, stop:0 #ffffff, stop:0.5 #ffffff, stop:0.6 #48a5fd, stop:1 #48a5fd); +} +QRadioButton::indicator:!checked { + border-color: #a9b7c6; + background-color: #fbfdfa; +} +QStatusBar { + color:#027f7f; +} + +QDial { + background: #16a085; +} + +QToolBox { + color: #a9b7c6; + background-color: #222b2e; +} +QToolBox::tab { + color: #a9b7c6; + background-color:#222b2e; +} +QToolBox::tab:selected { + color: #FFFFFF; + background-color:#222b2e; +} +QScrollArea { + color: #FFFFFF; + background-color:#222b2e; +} + +QScrollBar:horizontal { + max-height: 10px; + border: 1px transparent grey; + margin: 0px 20px 0px 20px; + background: transparent; +} +QScrollBar:vertical { + max-width: 10px; + border: 1px transparent grey; + margin: 20px 0px 20px 0px; + background: transparent; +} +QScrollBar::handle:vertical, QScrollBar::handle:horizontal { + background: #52595d; + border-style: transparent; + border-radius: 4px; + min-height: 25px; +} +QScrollBar::handle:horizontal:hover, QScrollBar::handle:vertical:hover { + background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #467dd1, stop:0.5 #3b88fc, stop:1 #467dd1); +} +QScrollBar::add-line, QScrollBar::sub-line { + border: 2px transparent grey; + border-radius: 4px; + subcontrol-origin: margin; + background: #b9b9b9; +} +QScrollBar::add-line:horizontal { + width: 20px; + subcontrol-position: right; +} +QScrollBar::add-line:vertical { + height: 20px; + subcontrol-position: bottom; +} +QScrollBar::sub-line:horizontal { + width: 20px; + subcontrol-position: left; +} +QScrollBar::sub-line:vertical { + height: 20px; + subcontrol-position: top; +} +QScrollBar::add-line:vertical:pressed, QScrollBar::add-line:horizontal:pressed, QScrollBar::sub-line:horizontal:pressed, QScrollBar::sub-line:vertical:pressed { + background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #467dd1, stop:0.5 #3b88fc, stop:1 #467dd1); +} +QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal, QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + background: none; +} +QScrollBar::up-arrow:vertical { + image: url(/usr/share/icons/Adwaita/16x16/actions/go-up-symbolic.symbolic.png); +} +QScrollBar::down-arrow:vertical { + image: url(/usr/share/icons/Adwaita/16x16/actions/go-down-symbolic.symbolic.png); +} +QScrollBar::left-arrow:horizontal { + image: url(/usr/share/icons/Adwaita/16x16/actions/go-previous-symbolic.symbolic.png); +} +QScrollBar::right-arrow:horizontal { + image: url(/usr/share/icons/Adwaita/16x16/actions/go-next-symbolic.symbolic.png); +} diff --git a/module/radio/styles/qss/ManjaroMix.qss b/module/radio/styles/qss/ManjaroMix.qss new file mode 100644 index 0000000..92301a5 --- /dev/null +++ b/module/radio/styles/qss/ManjaroMix.qss @@ -0,0 +1,531 @@ +/* +ManjaroMix Style Sheet for QT Applications +Author: Jaime A. Quiroga P. +Company: GTRONICK +Last updated: 25/02/2020, 15:42. +Available at: https://github.com/GTRONICK/QSS/blob/master/ManjaroMix.qss +*/ +QMainWindow { + background-color:#151a1e; +} +QCalendar { + background-color: #151a1e; +} +QTextEdit { + border-width: 1px; + border-style: solid; + border-color: #4fa08b; + background-color: #222b2e; + color: #d3dae3; +} +QPlainTextEdit { + border-width: 1px; + border-style: solid; + border-color: #4fa08b; + background-color: #222b2e; + color: #d3dae3; +} +QToolButton { + border-style: solid; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(215, 215, 215), stop:1 rgb(222, 222, 222)); + border-right-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(217, 217, 217), stop:1 rgb(227, 227, 227)); + border-left-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(227, 227, 227), stop:1 rgb(217, 217, 217)); + border-bottom-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(215, 215, 215), stop:1 rgb(222, 222, 222)); + border-width: 1px; + border-radius: 5px; + color: #d3dae3; + padding: 2px; + background-color: rgb(255,255,255); +} +QToolButton:hover{ + border-style: solid; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(195, 195, 195), stop:1 rgb(222, 222, 222)); + border-right-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(197, 197, 197), stop:1 rgb(227, 227, 227)); + border-left-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(227, 227, 227), stop:1 rgb(197, 197, 197)); + border-bottom-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(195, 195, 195), stop:1 rgb(222, 222, 222)); + border-width: 1px; + border-radius: 5px; + color: rgb(0,0,0); + padding: 2px; + background-color: rgb(255,255,255); +} +QToolButton:pressed{ + border-style: solid; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(215, 215, 215), stop:1 rgb(222, 222, 222)); + border-right-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(217, 217, 217), stop:1 rgb(227, 227, 227)); + border-left-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(227, 227, 227), stop:1 rgb(217, 217, 217)); + border-bottom-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(215, 215, 215), stop:1 rgb(222, 222, 222)); + border-width: 1px; + border-radius: 5px; + color: rgb(0,0,0); + padding: 2px; + background-color: rgb(142,142,142); +} +QPushButton{ + border-style: solid; + border-color: #050a0e; + border-width: 1px; + border-radius: 5px; + color: #d3dae3; + padding: 2px; + background-color: #151a1e; +} +QPushButton::default{ + border-style: solid; + border-color: #050a0e; + border-width: 1px; + border-radius: 5px; + color: #FFFFFF; + padding: 2px; + background-color: #151a1e;; +} +QPushButton:hover{ + border-style: solid; + border-color: #050a0e; + border-width: 1px; + border-radius: 5px; + color: #d3dae3; + padding: 2px; + background-color: #1c1f1f; +} +QPushButton:pressed{ + border-style: solid; + border-color: #050a0e; + border-width: 1px; + border-radius: 5px; + color: #d3dae3; + padding: 2px; + background-color: #2c2f2f; +} +QPushButton:disabled{ + border-style: solid; + border-top-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(215, 215, 215), stop:1 rgb(222, 222, 222)); + border-right-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(217, 217, 217), stop:1 rgb(227, 227, 227)); + border-left-color: qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgb(227, 227, 227), stop:1 rgb(217, 217, 217)); + border-bottom-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgb(215, 215, 215), stop:1 rgb(222, 222, 222)); + border-width: 1px; + border-radius: 5px; + color: #808086; + padding: 2px; + background-color: rgb(142,142,142); +} +QLineEdit { + border-width: 1px; + border-style: solid; + border-color: #4fa08b; + background-color: #222b2e; + color: #d3dae3; +} +QLabel { + color: #d3dae3; +} +QLCDNumber { + color: #4d9b87; +} +QProgressBar { + text-align: center; + color: #d3dae3; + border-radius: 10px; + border-color: transparent; + border-style: solid; + background-color: #52595d; +} +QProgressBar::chunk { + background-color: #214037 ; + border-radius: 10px; +} +QMenuBar { + background-color: #151a1e; +} +QMenuBar::item { + color: #d3dae3; + spacing: 3px; + padding: 1px 4px; + background-color: #151a1e; +} + +QMenuBar::item:selected { + background-color: #252a2e; + color: #FFFFFF; +} +QMenu { + background-color: #151a1e; +} +QMenu::item:selected { + background-color: #252a2e; + color: #FFFFFF; +} +QMenu::item { + color: #d3dae3; + background-color: #151a1e; +} +QTabWidget { + color:rgb(0,0,0); + background-color:#000000; +} +QTabWidget::pane { + border-color: #050a0e; + background-color: #1e282c; + border-style: solid; + border-width: 1px; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; +} +QTabBar::tab:first { + border-style: solid; + border-left-width:1px; + border-right-width:0px; + border-top-width:1px; + border-bottom-width:0px; + border-top-color: #050a0e; + border-left-color: #050a0e; + border-bottom-color: #050a0e; + border-top-left-radius: 4px; + color: #d3dae3; + padding: 3px; + margin-left:0px; + background-color: #151a1e; +} +QTabBar::tab:last { + border-style: solid; + border-top-width:1px; + border-left-width:1px; + border-right-width:1px; + border-bottom-width:0px; + border-color: #050a0e; + border-top-right-radius: 4px; + color: #d3dae3; + padding: 3px; + margin-left:0px; + background-color: #151a1e; +} +QTabBar::tab { + border-style: solid; + border-top-width:1px; + border-bottom-width:0px; + border-left-width:1px; + border-top-color: #050a0e; + border-left-color: #050a0e; + border-bottom-color: #050a0e; + color: #d3dae3; + padding: 3px; + margin-left:0px; + background-color: #151a1e; +} +QTabBar::tab:selected, QTabBar::tab:last:selected, QTabBar::tab:hover { + border-style: solid; + border-left-width:1px; + border-bottom-width:0px; + border-right-color: transparent; + border-top-color: #050a0e; + border-left-color: #050a0e; + border-bottom-color: #050a0e; + color: #FFFFFF; + padding: 3px; + margin-left:0px; + background-color: #1e282c; +} + +QTabBar::tab:selected, QTabBar::tab:first:selected, QTabBar::tab:hover { + border-style: solid; + border-left-width:1px; + border-bottom-width:0px; + border-top-width:1px; + border-right-color: transparent; + border-top-color: #050a0e; + border-left-color: #050a0e; + border-bottom-color: #050a0e; + color: #FFFFFF; + padding: 3px; + margin-left:0px; + background-color: #1e282c; +} + +QCheckBox { + color: #d3dae3; + padding: 2px; +} +QCheckBox:disabled { + color: #808086; + padding: 2px; +} + +QCheckBox:hover { + border-radius:4px; + border-style:solid; + padding-left: 1px; + padding-right: 1px; + padding-bottom: 1px; + padding-top: 1px; + border-width:1px; + border-color: transparent; +} +QCheckBox::indicator:checked { + + height: 10px; + width: 10px; + border-style:solid; + border-width: 1px; + border-color: #4fa08b; + color: #000000; + background-color: qradialgradient(cx:0.4, cy:0.4, radius: 1.5,fx:0, fy:0, stop:0 #1e282c, stop:0.3 #1e282c, stop:0.4 #4fa08b, stop:0.5 #1e282c, stop:1 #1e282c); +} +QCheckBox::indicator:unchecked { + + height: 10px; + width: 10px; + border-style:solid; + border-width: 1px; + border-color: #4fa08b; + color: #000000; +} +QRadioButton { + color: #d3dae3; + padding: 1px; +} +QRadioButton::indicator:checked { + height: 10px; + width: 10px; + border-style:solid; + border-radius:5px; + border-width: 1px; + border-color: #4fa08b; + color: #a9b7c6; + background-color: qradialgradient(cx:0.5, cy:0.5, radius:0.4,fx:0.5, fy:0.5, stop:0 #4fa08b, stop:1 #1e282c); +} +QRadioButton::indicator:!checked { + height: 10px; + width: 10px; + border-style:solid; + border-radius:5px; + border-width: 1px; + border-color: #4fa08b; + color: #a9b7c6; + background-color: transparent; +} +QStatusBar { + color:#027f7f; +} +QSpinBox { + color: #d3dae3; + background-color: #222b2e; + border-width: 1px; + border-style: solid; + border-color: #4fa08b; +} +QDoubleSpinBox { + color: #d3dae3; + background-color: #222b2e; + border-width: 1px; + border-style: solid; + border-color: #4fa08b; +} +QTimeEdit { + color: #d3dae3; + background-color: #222b2e; + border-width: 1px; + border-style: solid; + border-color: #4fa08b; +} +QDateTimeEdit { + color: #d3dae3; + background-color: #222b2e; + border-width: 1px; + border-style: solid; + border-color: #4fa08b; +} +QDateEdit { + color: #d3dae3; + background-color: #222b2e; + border-width: 1px; + border-style: solid; + border-color: #4fa08b; +} +QFontComboBox { + color: #d3dae3; + background-color: #222b2e; + border-width: 1px; + border-style: solid; + border-color: #4fa08b; +} +QComboBox { + color: #d3dae3; + background-color: #222b2e; + border-width: 1px; + border-style: solid; + border-color: #4fa08b; +} + +QDial { + background: #16a085; +} + +QToolBox { + color: #a9b7c6; + background-color: #222b2e; +} +QToolBox::tab { + color: #a9b7c6; + background-color:#222b2e; +} +QToolBox::tab:selected { + color: #FFFFFF; + background-color:#222b2e; +} +QScrollArea { + color: #FFFFFF; + background-color:#222b2e; +} +QSlider::groove:horizontal { + height: 5px; + background-color: #52595d; +} +QSlider::groove:vertical { + width: 5px; + background-color: #52595d; +} +QSlider::handle:horizontal { + background: #1a2224; + border-style: solid; + border-width: 1px; + border-color: rgb(207,207,207); + width: 12px; + margin: -5px 0; + border-radius: 7px; +} +QSlider::handle:vertical { + background: #1a2224; + border-style: solid; + border-width: 1px; + border-color: rgb(207,207,207); + height: 12px; + margin: 0 -5px; + border-radius: 7px; +} +QSlider::add-page:horizontal { + background: #52595d; +} +QSlider::add-page:vertical { + background: #52595d; +} +QSlider::sub-page:horizontal { + background-color: #15433a; +} +QSlider::sub-page:vertical { + background-color: #15433a; +} +QScrollBar:horizontal { + max-height: 10px; + border: 1px transparent grey; + margin: 0px 20px 0px 20px; + background: transparent; +} +QScrollBar:vertical { + max-width: 10px; + border: 1px transparent grey; + margin: 20px 0px 20px 0px; + background: transparent; +} +QScrollBar::handle:horizontal { + background: #52595d; + border-style: transparent; + border-radius: 4px; + min-width: 25px; +} +QScrollBar::handle:horizontal:hover { + background: #58a492; + border-style: transparent; + border-radius: 4px; + min-width: 25px; +} +QScrollBar::handle:vertical { + background: #52595d; + border-style: transparent; + border-radius: 4px; + min-height: 25px; +} +QScrollBar::handle:vertical:hover { + background: #58a492; + border-style: transparent; + border-radius: 4px; + min-height: 25px; +} +QScrollBar::add-line:horizontal { + border: 2px transparent grey; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + background: #15433a; + width: 20px; + subcontrol-position: right; + subcontrol-origin: margin; +} +QScrollBar::add-line:horizontal:pressed { + border: 2px transparent grey; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + background: rgb(181,181,181); + width: 20px; + subcontrol-position: right; + subcontrol-origin: margin; +} +QScrollBar::add-line:vertical { + border: 2px transparent grey; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + background: #15433a; + height: 20px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} +QScrollBar::add-line:vertical:pressed { + border: 2px transparent grey; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + background: rgb(181,181,181); + height: 20px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} +QScrollBar::sub-line:horizontal { + border: 2px transparent grey; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + background: #15433a; + width: 20px; + subcontrol-position: left; + subcontrol-origin: margin; +} +QScrollBar::sub-line:horizontal:pressed { + border: 2px transparent grey; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + background: rgb(181,181,181); + width: 20px; + subcontrol-position: left; + subcontrol-origin: margin; +} +QScrollBar::sub-line:vertical { + border: 2px transparent grey; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + background: #15433a; + height: 20px; + subcontrol-position: top; + subcontrol-origin: margin; +} +QScrollBar::sub-line:vertical:pressed { + border: 2px transparent grey; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + background: rgb(181,181,181); + height: 20px; + subcontrol-position: top; + subcontrol-origin: margin; +} + +QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal { + background: none; +} +QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + background: none; +} diff --git a/module/radio/styles/qss/MaterialDark.qss b/module/radio/styles/qss/MaterialDark.qss new file mode 100644 index 0000000..c5a94aa --- /dev/null +++ b/module/radio/styles/qss/MaterialDark.qss @@ -0,0 +1,390 @@ +/* +Material Dark Style Sheet for QT Applications +Author: Jaime A. Quiroga P. +Inspired on https://github.com/jxfwinter/qt-material-stylesheet +Company: GTRONICK +Last updated: 04/12/2018, 15:00. +Available at: https://github.com/GTRONICK/QSS/blob/master/MaterialDark.qss +*/ +QMainWindow { + background-color:#1e1d23; +} +QDialog { + background-color:#1e1d23; +} +QColorDialog { + background-color:#1e1d23; +} +QTextEdit { + background-color:#1e1d23; + color: #a9b7c6; +} +QPlainTextEdit { + selection-background-color:#007b50; + background-color:#1e1d23; + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: transparent; + border-width: 1px; + color: #a9b7c6; +} +QPushButton{ + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: transparent; + border-width: 1px; + border-style: solid; + color: #a9b7c6; + padding: 2px; + background-color: #1e1d23; +} +QPushButton::default{ + border-style: inset; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: #04b97f; + border-width: 1px; + color: #a9b7c6; + padding: 2px; + background-color: #1e1d23; +} +QToolButton { + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: #04b97f; + border-bottom-width: 1px; + border-style: solid; + color: #a9b7c6; + padding: 2px; + background-color: #1e1d23; +} +QToolButton:hover{ + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: #37efba; + border-bottom-width: 2px; + border-style: solid; + color: #FFFFFF; + padding-bottom: 1px; + background-color: #1e1d23; +} +QPushButton:hover{ + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: #37efba; + border-bottom-width: 1px; + border-style: solid; + color: #FFFFFF; + padding-bottom: 2px; + background-color: #1e1d23; +} +QPushButton:pressed{ + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: #37efba; + border-bottom-width: 2px; + border-style: solid; + color: #37efba; + padding-bottom: 1px; + background-color: #1e1d23; +} +QPushButton:disabled{ + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: #808086; + border-bottom-width: 2px; + border-style: solid; + color: #808086; + padding-bottom: 1px; + background-color: #1e1d23; +} +QLineEdit { + border-width: 1px; border-radius: 4px; + border-color: rgb(58, 58, 58); + border-style: inset; + padding: 0 8px; + color: #a9b7c6; + background:#1e1d23; + selection-background-color:#007b50; + selection-color: #FFFFFF; +} +QLabel { + color: #a9b7c6; +} +QLCDNumber { + color: #37e6b4; +} +QProgressBar { + text-align: center; + color: rgb(240, 240, 240); + border-width: 1px; + border-radius: 10px; + border-color: rgb(58, 58, 58); + border-style: inset; + background-color:#1e1d23; +} +QProgressBar::chunk { + background-color: #04b97f; + border-radius: 5px; +} +QMenuBar { + background-color: #1e1d23; +} +QMenuBar::item { + color: #a9b7c6; + spacing: 3px; + padding: 1px 4px; + background: #1e1d23; +} + +QMenuBar::item:selected { + background:#1e1d23; + color: #FFFFFF; +} +QMenu::item:selected { + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: #04b97f; + border-bottom-color: transparent; + border-left-width: 2px; + color: #FFFFFF; + padding-left:15px; + padding-top:4px; + padding-bottom:4px; + padding-right:7px; + background-color: #1e1d23; +} +QMenu::item { + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: transparent; + border-bottom-width: 1px; + border-style: solid; + color: #a9b7c6; + padding-left:17px; + padding-top:4px; + padding-bottom:4px; + padding-right:7px; + background-color: #1e1d23; +} +QMenu{ + background-color:#1e1d23; +} +QTabWidget { + color:rgb(0,0,0); + background-color:#1e1d23; +} +QTabWidget::pane { + border-color: rgb(77,77,77); + background-color:#1e1d23; + border-style: solid; + border-width: 1px; + border-radius: 6px; +} +QTabBar::tab { + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: transparent; + border-bottom-width: 1px; + border-style: solid; + color: #808086; + padding: 3px; + margin-left:3px; + background-color: #1e1d23; +} +QTabBar::tab:selected, QTabBar::tab:last:selected, QTabBar::tab:hover { + border-style: solid; + border-top-color: transparent; + border-right-color: transparent; + border-left-color: transparent; + border-bottom-color: #04b97f; + border-bottom-width: 2px; + border-style: solid; + color: #FFFFFF; + padding-left: 3px; + padding-bottom: 2px; + margin-left:3px; + background-color: #1e1d23; +} + +QCheckBox { + color: #a9b7c6; + padding: 2px; +} +QCheckBox:disabled { + color: #808086; + padding: 2px; +} + +QCheckBox:hover { + border-radius:4px; + border-style:solid; + padding-left: 1px; + padding-right: 1px; + padding-bottom: 1px; + padding-top: 1px; + border-width:1px; + border-color: rgb(87, 97, 106); + background-color:#1e1d23; +} +QCheckBox::indicator:checked { + + height: 10px; + width: 10px; + border-style:solid; + border-width: 1px; + border-color: #04b97f; + color: #a9b7c6; + background-color: #04b97f; +} +QCheckBox::indicator:unchecked { + + height: 10px; + width: 10px; + border-style:solid; + border-width: 1px; + border-color: #04b97f; + color: #a9b7c6; + background-color: transparent; +} +QRadioButton { + color: #a9b7c6; + background-color: #1e1d23; + padding: 1px; +} +QRadioButton::indicator:checked { + height: 10px; + width: 10px; + border-style:solid; + border-radius:5px; + border-width: 1px; + border-color: #04b97f; + color: #a9b7c6; + background-color: #04b97f; +} +QRadioButton::indicator:!checked { + height: 10px; + width: 10px; + border-style:solid; + border-radius:5px; + border-width: 1px; + border-color: #04b97f; + color: #a9b7c6; + background-color: transparent; +} +QStatusBar { + color:#027f7f; +} +QSpinBox { + color: #a9b7c6; + background-color: #1e1d23; +} +QDoubleSpinBox { + color: #a9b7c6; + background-color: #1e1d23; +} +QTimeEdit { + color: #a9b7c6; + background-color: #1e1d23; +} +QDateTimeEdit { + color: #a9b7c6; + background-color: #1e1d23; +} +QDateEdit { + color: #a9b7c6; + background-color: #1e1d23; +} +QComboBox { + color: #a9b7c6; + background: #1e1d23; +} +QComboBox:editable { + background: #1e1d23; + color: #a9b7c6; + selection-background-color: #1e1d23; +} +QComboBox QAbstractItemView { + color: #a9b7c6; + background: #1e1d23; + selection-color: #FFFFFF; + selection-background-color: #1e1d23; +} +QComboBox:!editable:on, QComboBox::drop-down:editable:on { + color: #a9b7c6; + background: #1e1d23; +} +QFontComboBox { + color: #a9b7c6; + background-color: #1e1d23; +} +QToolBox { + color: #a9b7c6; + background-color: #1e1d23; +} +QToolBox::tab { + color: #a9b7c6; + background-color: #1e1d23; +} +QToolBox::tab:selected { + color: #FFFFFF; + background-color: #1e1d23; +} +QScrollArea { + color: #FFFFFF; + background-color: #1e1d23; +} +QSlider::groove:horizontal { + height: 5px; + background: #04b97f; +} +QSlider::groove:vertical { + width: 5px; + background: #04b97f; +} +QSlider::handle:horizontal { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #b4b4b4, stop:1 #8f8f8f); + border: 1px solid #5c5c5c; + width: 14px; + margin: -5px 0; + border-radius: 7px; +} +QSlider::handle:vertical { + background: qlineargradient(x1:1, y1:1, x2:0, y2:0, stop:0 #b4b4b4, stop:1 #8f8f8f); + border: 1px solid #5c5c5c; + height: 14px; + margin: 0 -5px; + border-radius: 7px; +} +QSlider::add-page:horizontal { + background: white; +} +QSlider::add-page:vertical { + background: white; +} +QSlider::sub-page:horizontal { + background: #04b97f; +} +QSlider::sub-page:vertical { + background: #04b97f; +} diff --git a/module/radio/styles/qss/NeonButtons.qss b/module/radio/styles/qss/NeonButtons.qss new file mode 100644 index 0000000..8065250 --- /dev/null +++ b/module/radio/styles/qss/NeonButtons.qss @@ -0,0 +1,47 @@ +/* +Neon Style Sheet for QT Applications (QpushButton) +Author: Jaime A. Quiroga P. +Company: GTRONICK +Last updated: 24/10/2020, 15:42. +Available at: https://github.com/GTRONICK/QSS/blob/master/NeonButtons.qss +*/ +QPushButton{ + border-style: solid; + border-color: #050a0e; + border-width: 1px; + border-radius: 5px; + color: #d3dae3; + padding: 2px; + background-color: #100E19; +} +QPushButton::default{ + border-style: solid; + border-color: #050a0e; + border-width: 1px; + border-radius: 5px; + color: #FFFFFF; + padding: 2px; + background-color: #151a1e; +} +QPushButton:hover{ + border-style: solid; + border-top-color: qlineargradient(spread:pad, x1:0, y1:1, x2:1, y2:1, stop:0 #C0DB50, stop:0.4 #C0DB50, stop:0.5 #100E19, stop:1 #100E19); + border-bottom-color: qlineargradient(spread:pad, x1:0, y1:1, x2:1, y2:1, stop:0 #100E19, stop:0.5 #100E19, stop:0.6 #C0DB50, stop:1 #C0DB50); + border-left-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #C0DB50, stop:0.3 #C0DB50, stop:0.7 #100E19, stop:1 #100E19); + border-right-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 #C0DB50, stop:0.3 #C0DB50, stop:0.7 #100E19, stop:1 #100E19); + border-width: 2px; + border-radius: 1px; + color: #d3dae3; + padding: 2px; +} +QPushButton:pressed{ + border-style: solid; + border-top-color: qlineargradient(spread:pad, x1:0, y1:1, x2:1, y2:1, stop:0 #d33af1, stop:0.4 #d33af1, stop:0.5 #100E19, stop:1 #100E19); + border-bottom-color: qlineargradient(spread:pad, x1:0, y1:1, x2:1, y2:1, stop:0 #100E19, stop:0.5 #100E19, stop:0.6 #d33af1, stop:1 #d33af1); + border-left-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #d33af1, stop:0.3 #d33af1, stop:0.7 #100E19, stop:1 #100E19); + border-right-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 #d33af1, stop:0.3 #d33af1, stop:0.7 #100E19, stop:1 #100E19); + border-width: 2px; + border-radius: 1px; + color: #d3dae3; + padding: 2px; +} \ No newline at end of file diff --git a/module/radio/styles/qss/QSS_IMG/go-down-symbolic.symbolic.png b/module/radio/styles/qss/QSS_IMG/go-down-symbolic.symbolic.png new file mode 100644 index 0000000..e69de29 diff --git a/module/radio/styles/qss/QSS_IMG/go-next-symbolic.symbolic.png b/module/radio/styles/qss/QSS_IMG/go-next-symbolic.symbolic.png new file mode 100644 index 0000000..e69de29 diff --git a/module/radio/styles/qss/QSS_IMG/go-previous-symbolic.symbolic.png b/module/radio/styles/qss/QSS_IMG/go-previous-symbolic.symbolic.png new file mode 100644 index 0000000..e69de29 diff --git a/module/radio/styles/qss/QSS_IMG/go-up-symbolic.symbolic.png b/module/radio/styles/qss/QSS_IMG/go-up-symbolic.symbolic.png new file mode 100644 index 0000000..e69de29 diff --git a/module/radio/styles/qss/QSS_IMG/object-select-symbolic.symbolic.png b/module/radio/styles/qss/QSS_IMG/object-select-symbolic.symbolic.png new file mode 100644 index 0000000..e69de29 diff --git a/module/radio/styles/qss/README.md b/module/radio/styles/qss/README.md new file mode 100644 index 0000000..e9a5cb6 --- /dev/null +++ b/module/radio/styles/qss/README.md @@ -0,0 +1,49 @@ +### QT StyleSheet templates ### + +Themes available: + +1. [Ubuntu](https://github.com/GTRONICK/QSS/blob/master/Ubuntu.qss) + +![Ubuntu theme screenshot](https://i.imgur.com/i8zVYwL.png) + +2. [ElegantDark](https://github.com/GTRONICK/QSS/blob/master/ElegantDark.qss) + +![ElegantDark theme screenshot](https://i.imgur.com/AUb7R7P.png) + +3. [MaterialDark](https://github.com/GTRONICK/QSS/blob/master/MaterialDark.qss) + +![MaterialDark theme screenshot](https://i.imgur.com/ViEQxdh.png) + +4. [ConsoleStyle](https://github.com/GTRONICK/QSS/blob/master/ConsoleStyle.qss) + +![ConsoleStyle theme screenshot](https://i.imgur.com/E10ukaA.png) + +5. [AMOLED](https://github.com/GTRONICK/QSS/blob/master/AMOLED.qss) + +![AMOLED theme screenshot](https://i.imgur.com/M7RIx4c.png) + +6. [Aqua](https://github.com/GTRONICK/QSS/blob/master/Aqua.qss) + +![Aqua theme screenshot](https://i.imgur.com/i8zVYwL.png) + +## The ManjaroMix Theme!: Includes a radial gradient for Checkboxes, and minimalist arrows for scrollbars. ## + +7. [ManjaroMix](https://github.com/GTRONICK/QSS/blob/master/ManjaroMix.qss) + +![ManjaroMix theme screenshot](https://i.imgur.com/7zrMDMH.png) + +8. [NeonButtons](https://github.com/GTRONICK/QSS/blob/master/NeonButtons.qss) + +![NeonButtons screenshot](https://i.imgur.com/IqTSQG2.png) +![NeonButtons screenshot](https://i.imgur.com/l4im5Ve.png) + +## MacOS Theme!: Reduced code, image integration through URL resources. ## + +9. [MacOS](https://github.com/GTRONICK/QSS/blob/master/MacOS.qss) + +![MacOS](https://i.imgur.com/quEgiVe.png) +**Added images in QSS_IMG folder** + +Stay tunned!, this files are being updated frequently. +*Consider donating :)* **PayPal Account:** gtronick@gmail.com + diff --git a/module/radio/styles/qss/Ubuntu.qss b/module/radio/styles/qss/Ubuntu.qss new file mode 100644 index 0000000..5f713c1 --- /dev/null +++ b/module/radio/styles/qss/Ubuntu.qss @@ -0,0 +1,496 @@ +/* +Ubuntu Style Sheet for QT Applications +Author: Jaime A. Quiroga P. +Company: GTRONICK +Last updated: 01/10/2021 (dd/mm/yyyy), 15:18. +Available at: https://github.com/GTRONICK/QSS/blob/master/Ubuntu.qss +*/ +QMainWindow { + background-color:#f0f0f0; +} +QCheckBox { + padding:2px; +} +QCheckBox:hover { + border:1px solid rgb(255,150,60); + border-radius:4px; + padding: 1px; + background-color:qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(190, 90, 50, 50), stop:1 rgba(250, 130, 40, 50)); +} +QCheckBox::indicator:checked { + border:1px solid rgb(246, 134, 86); + border-radius:4px; + background-color:rgb(246, 134, 86) +} +QCheckBox::indicator:unchecked { + border-width:1px solid rgb(246, 134, 86); + border-radius:4px; + background-color:rgb(255,255,255); +} +QColorDialog { + background-color:#f0f0f0; +} +QComboBox { + color:rgb(81,72,65); + background: #ffffff; +} +QComboBox:editable { + selection-color:rgb(81,72,65); + selection-background-color: #ffffff; +} +QComboBox QAbstractItemView { + selection-color: #ffffff; + selection-background-color: rgb(246, 134, 86); +} +QComboBox:!editable:on, QComboBox::drop-down:editable:on { + color: #1e1d23; +} +QDateTimeEdit, QDateEdit, QDoubleSpinBox, QFontComboBox { + color:rgb(81,72,65); + background-color: #ffffff; +} + +QDialog { + background-color:#f0f0f0; +} + +QLabel,QLineEdit { + color:rgb(17,17,17); +} +QLineEdit { + background-color:rgb(255,255,255); + selection-background-color:rgb(236,116,64); +} +QMenuBar { + color:rgb(223,219,210); + background-color:rgb(65,64,59); +} +QMenuBar::item { + padding-top:4px; + padding-left:4px; + padding-right:4px; + color:rgb(223,219,210); + background-color:rgb(65,64,59); +} +QMenuBar::item:selected { + color:rgb(255,255,255); + padding-top:2px; + padding-left:2px; + padding-right:2px; + border-top-width:2px; + border-left-width:2px; + border-right-width:2px; + border-top-right-radius:4px; + border-top-left-radius:4px; + border-style:solid; + background-color:rgb(65,64,59); + border-top-color: rgb(47,47,44); + border-right-color: qlineargradient(spread:pad, x1:0, y1:1, x2:1, y2:0, stop:0 rgba(90, 87, 78, 255), stop:1 rgba(47,47,44, 255)); + border-left-color: qlineargradient(spread:pad, x1:1, y1:0, x2:0, y2:0, stop:0 rgba(90, 87, 78, 255), stop:1 rgba(47,47,44, 255)); +} +QMenu { + color:rgb(223,219,210); + background-color:rgb(65,64,59); +} +QMenu::item { + color:rgb(223,219,210); + padding:4px 10px 4px 20px; +} +QMenu::item:selected { + color:rgb(255,255,255); + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(225, 108, 54, 255), stop:1 rgba(246, 134, 86, 255)); + border-style:solid; + border-width:3px; + padding:4px 7px 4px 17px; + border-bottom-color:qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(175,85,48,255), stop:1 rgba(236,114,67, 255)); + border-top-color:qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(253,156,113,255), stop:1 rgba(205,90,46, 255)); + border-right-color:qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgba(253,156,113,255), stop:1 rgba(205,90,46, 255)); + border-left-color:qlineargradient(spread:pad, x1:1, y1:0.5, x2:0, y2:0.5, stop:0 rgba(253,156,113,255), stop:1 rgba(205,90,46, 255)); +} +QPlainTextEdit { + border: 1px solid transparent; + color:rgb(17,17,17); + selection-background-color:rgb(236,116,64); + background-color: #FFFFFF; +} +QProgressBar { + text-align: center; + color: rgb(0, 0, 0); + border: 1px inset rgb(150,150,150); + border-radius: 10px; + background-color:rgb(221,221,219); +} +QProgressBar::chunk:horizontal { + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(225, 108, 54, 255), stop:1 rgba(246, 134, 86, 255)); + border:1px solid; + border-radius:8px; + border-bottom-color:qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(175,85,48,255), stop:1 rgba(236,114,67, 255)); + border-top-color:qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(253,156,113,255), stop:1 rgba(205,90,46, 255)); + border-right-color:qlineargradient(spread:pad, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 rgba(253,156,113,255), stop:1 rgba(205,90,46, 255)); + border-left-color:qlineargradient(spread:pad, x1:1, y1:0.5, x2:0, y2:0.5, stop:0 rgba(253,156,113,255), stop:1 rgba(205,90,46, 255)); +} +QPushButton{ + color:rgb(17,17,17); + border-width: 1px; + border-radius: 6px; + border-bottom-color: rgb(150,150,150); + border-right-color: rgb(165,165,165); + border-left-color: rgb(165,165,165); + border-top-color: rgb(180,180,180); + border-style: solid; + padding: 4px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(220, 220, 220, 255), stop:1 rgba(255, 255, 255, 255)); +} +QPushButton:hover{ + color:rgb(17,17,17); + border-width: 1px; + border-radius:6px; + border-top-color: rgb(255,150,60); + border-right-color: qlineargradient(spread:pad, x1:0, y1:1, x2:1, y2:0, stop:0 rgba(200, 70, 20, 255), stop:1 rgba(255,150,60, 255)); + border-left-color: qlineargradient(spread:pad, x1:1, y1:0, x2:0, y2:0, stop:0 rgba(200, 70, 20, 255), stop:1 rgba(255,150,60, 255)); + border-bottom-color: rgb(200,70,20); + border-style: solid; + padding: 2px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(220, 220, 220, 255), stop:1 rgba(255, 255, 255, 255)); +} +QPushButton:default{ + color:rgb(17,17,17); + border-width: 1px; + border-radius:6px; + border-top-color: rgb(255,150,60); + border-right-color: qlineargradient(spread:pad, x1:0, y1:1, x2:1, y2:0, stop:0 rgba(200, 70, 20, 255), stop:1 rgba(255,150,60, 255)); + border-left-color: qlineargradient(spread:pad, x1:1, y1:0, x2:0, y2:0, stop:0 rgba(200, 70, 20, 255), stop:1 rgba(255,150,60, 255)); + border-bottom-color: rgb(200,70,20); + border-style: solid; + padding: 2px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(220, 220, 220, 255), stop:1 rgba(255, 255, 255, 255)); +} +QPushButton:pressed{ + color:rgb(17,17,17); + border-width: 1px; + border-radius: 6px; + border-width: 1px; + border-top-color: rgba(255,150,60,200); + border-right-color: qlineargradient(spread:pad, x1:0, y1:1, x2:1, y2:0, stop:0 rgba(200, 70, 20, 255), stop:1 rgba(255,150,60, 200)); + border-left-color: qlineargradient(spread:pad, x1:1, y1:0, x2:0, y2:0, stop:0 rgba(200, 70, 20, 255), stop:1 rgba(255,150,60, 200)); + border-bottom-color: rgba(200,70,20,200); + border-style: solid; + padding: 2px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 rgba(220, 220, 220, 255), stop:1 rgba(255, 255, 255, 255)); +} +QPushButton:disabled{ + color:rgb(174,167,159); + border-width: 1px; + border-radius: 6px; + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(200, 200, 200, 255), stop:1 rgba(230, 230, 230, 255)); +} +QRadioButton { + padding: 1px; +} +QRadioButton::indicator:checked { + height: 10px; + width: 10px; + border-style:solid; + border-radius:5px; + border-width: 1px; + border-color: rgba(246, 134, 86, 255); + color: #a9b7c6; + background-color:rgba(246, 134, 86, 255); +} +QRadioButton::indicator:!checked { + height: 10px; + width: 10px; + border-style:solid; + border-radius:5px; + border-width: 1px; + border-color: rgb(246, 134, 86); + color: #a9b7c6; + background-color: transparent; +} +QScrollArea { + color: white; + background-color:#f0f0f0; +} +QSlider::groove { + border-style: solid; + border-width: 1px; + border-color: rgb(207,207,207); +} +QSlider::groove:horizontal { + height: 5px; + background: rgb(246, 134, 86); +} +QSlider::groove:vertical { + width: 5px; + background: rgb(246, 134, 86); +} +QSlider::handle:horizontal { + background: rgb(253,253,253); + border-style: solid; + border-width: 1px; + border-color: rgb(207,207,207); + width: 12px; + margin: -5px 0; + border-radius: 7px; +} +QSlider::handle:vertical { + background: rgb(253,253,253); + border-style: solid; + border-width: 1px; + border-color: rgb(207,207,207); + height: 12px; + margin: 0 -5px; + border-radius: 7px; +} +QSlider::add-page:horizontal, QSlider::add-page:vertical { + background: white; +} +QSlider::sub-page:horizontal, QSlider::sub-page:vertical { + background: rgb(246, 134, 86); +} +QStatusBar, QSpinBox { + color:rgb(81,72,65); +} +QSpinBox { + background-color: #ffffff; +} +QScrollBar:horizontal { + max-height: 20px; + border: 1px transparent; + margin: 0px 20px 0px 20px; +} +QScrollBar::handle:horizontal { + background: rgb(253,253,253); + border: 1px solid rgb(207,207,207); + border-radius: 7px; + min-width: 25px; +} +QScrollBar::handle:horizontal:hover { + background: rgb(253,253,253); + border: 1px solid rgb(255,150,60); + border-radius: 7px; + min-width: 25px; +} +QScrollBar::add-line:horizontal { + border: 1px solid rgb(207,207,207); + border-top-right-radius: 7px; + border-top-left-radius: 7px; + border-bottom-right-radius: 7px; + background: rgb(255, 255, 255); + width: 20px; + subcontrol-position: right; + subcontrol-origin: margin; +} +QScrollBar::add-line:horizontal:hover { + border: 1px solid rgb(255,150,60); + border-top-right-radius: 7px; + border-top-left-radius: 7px; + border-bottom-right-radius: 7px; + background: rgb(255, 255, 255); + width: 20px; + subcontrol-position: right; + subcontrol-origin: margin; +} +QScrollBar::add-line:horizontal:pressed { + border: 1px solid grey; + border-top-left-radius: 7px; + border-top-right-radius: 7px; + border-bottom-right-radius: 7px; + background: rgb(231,231,231); + width: 20px; + subcontrol-position: right; + subcontrol-origin: margin; +} +QScrollBar::sub-line:horizontal { + border: 1px solid rgb(207,207,207); + border-top-right-radius: 7px; + border-top-left-radius: 7px; + border-bottom-left-radius: 7px; + background: rgb(255, 255, 255); + width: 20px; + subcontrol-position: left; + subcontrol-origin: margin; +} +QScrollBar::sub-line:horizontal:hover { + border: 1px solid rgb(255,150,60); + border-top-right-radius: 7px; + border-top-left-radius: 7px; + border-bottom-left-radius: 7px; + background: rgb(255, 255, 255); + width: 20px; + subcontrol-position: left; + subcontrol-origin: margin; +} +QScrollBar::sub-line:horizontal:pressed { + border: 1px solid grey; + border-top-right-radius: 7px; + border-top-left-radius: 7px; + border-bottom-left-radius: 7px; + background: rgb(231,231,231); + width: 20px; + subcontrol-position: left; + subcontrol-origin: margin; +} +QScrollBar::left-arrow:horizontal { + border: 1px transparent grey; + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; + width: 6px; + height: 6px; + background: rgb(230,230,230); +} +QScrollBar::right-arrow:horizontal { + border: 1px transparent grey; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + width: 6px; + height: 6px; + background: rgb(230,230,230); +} +QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal { + background: none; +} +QScrollBar:vertical { + max-width: 20px; + border: 1px transparent grey; + margin: 20px 0px 20px 0px; +} +QScrollBar::add-line:vertical { + border: 1px solid; + border-color: rgb(207,207,207); + border-bottom-right-radius: 7px; + border-bottom-left-radius: 7px; + border-top-left-radius: 7px; + background: rgb(255, 255, 255); + height: 20px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} +QScrollBar::add-line:vertical:hover { + border: 1px solid; + border-color: rgb(255,150,60); + border-bottom-right-radius: 7px; + border-bottom-left-radius: 7px; + border-top-left-radius: 7px; + background: rgb(255, 255, 255); + height: 20px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} +QScrollBar::add-line:vertical:pressed { + border: 1px solid grey; + border-bottom-left-radius: 7px; + border-bottom-right-radius: 7px; + border-top-left-radius: 7px; + background: rgb(231,231,231); + height: 20px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} +QScrollBar::sub-line:vertical { + border: 1px solid rgb(207,207,207); + border-top-right-radius: 7px; + border-top-left-radius: 7px; + border-bottom-left-radius: 7px; + background: rgb(255, 255, 255); + height: 20px; + subcontrol-position: top; + subcontrol-origin: margin; +} +QScrollBar::sub-line:vertical:hover { + border: 1px solid rgb(255,150,60); + border-top-right-radius: 7px; + border-top-left-radius: 7px; + border-bottom-left-radius: 7px; + background: rgb(255, 255, 255); + height: 20px; + subcontrol-position: top; + subcontrol-origin: margin; +} +QScrollBar::sub-line:vertical:pressed { + border: 1px solid grey; + border-top-left-radius: 7px; + border-top-right-radius: 7px; + background: rgb(231,231,231); + height: 20px; + subcontrol-position: top; + subcontrol-origin: margin; +} +QScrollBar::handle:vertical { + background: rgb(253,253,253); + border: 1px solid rgb(207,207,207); + border-radius: 7px; + min-height: 25px; +} +QScrollBar::handle:vertical:hover { + background: rgb(253,253,253); + border: 1px solid rgb(255,150,60); + border-radius: 7px; + min-height: 25px; +} +QScrollBar::up-arrow:vertical { + border: 1px transparent grey; + border-top-left-radius: 3px; + border-top-right-radius: 3px; + width: 6px; + height: 6px; + background: rgb(230,230,230); +} +QScrollBar::down-arrow:vertical { + border: 1px transparent grey; + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; + width: 6px; + height: 6px; + background: rgb(230,230,230); +} +QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + background: none; +} +QTabWidget { + color:rgb(0,0,0); + background-color:rgb(247,246,246); +} +QTabWidget::pane { + border-color: rgb(180,180,180); + background-color:rgb(247,246,246); + border-style: solid; + border-width: 1px; + border-radius: 6px; +} +QTabBar::tab { + padding-left:4px; + padding-right:4px; + padding-bottom:2px; + padding-top:2px; + color:rgb(81,72,65); + background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, stop:0 rgba(221,218,217,255), stop:1 rgba(240,239,238,255)); + border-style: solid; + border-width: 1px; + border-top-right-radius:4px; + border-top-left-radius:4px; + border-top-color: rgb(180,180,180); + border-left-color: rgb(180,180,180); + border-right-color: rgb(180,180,180); + border-bottom-color: transparent; +} +QTabBar::tab:selected, QTabBar::tab:last:selected, QTabBar::tab:hover { + background-color:rgb(247,246,246); + margin-left: 0px; + margin-right: 1px; +} +QTabBar::tab:!selected { + margin-top: 1px; + margin-right: 1px; +} +QTextEdit { + border-width: 1px; + border-style: solid; + border-color:transparent; + color:rgb(17,17,17); + selection-background-color:rgb(236,116,64); +} +QTimeEdit, QToolBox, QToolBox::tab, QToolBox::tab:selected { + color:rgb(81,72,65); + background-color: #ffffff; +} diff --git a/module/radio/styles/qss/qss.qrc b/module/radio/styles/qss/qss.qrc new file mode 100644 index 0000000..d821fad --- /dev/null +++ b/module/radio/styles/qss/qss.qrc @@ -0,0 +1,13 @@ + + + AMOLED.qss + Aqua.qss + ConsoleStyle.qss + ElegantDark.qss + MacOS.qss + ManjaroMix.qss + MaterialDark.qss + NeonButtons.qss + Ubuntu.qss + + diff --git a/module/radio/styles/styles.qrc b/module/radio/styles/styles.qrc new file mode 100644 index 0000000..2b88313 --- /dev/null +++ b/module/radio/styles/styles.qrc @@ -0,0 +1,7 @@ + + + + images/woodbutton.png + images/woodbackground.png + + diff --git a/module/radio/subWidget/ServerSettingWidget.cpp b/module/radio/subWidget/ServerSettingWidget.cpp new file mode 100644 index 0000000..2f8a200 --- /dev/null +++ b/module/radio/subWidget/ServerSettingWidget.cpp @@ -0,0 +1,124 @@ +#include "ServerSettingWidget.h" +#include +#include +#include +#include +#include "../component/ExpandInput.h" +#include "../component/ShowHelpInfo.h" +#include "../BackEnd/MainWidget.h" +#include "../BaseWidget.h" + + +ServerSettingWidget::ServerSettingWidget(QWidget *parent) : QWidget(parent) { + + + setObjectName("服务端设置界面"); + hide(); + auto mainLayout = new QVBoxLayout(this); + mainLayout->setAlignment(Qt::AlignTop); + mRigNameLabel = createLabel("Rig Name"); + mUserNameLabel = createLabel("User Name"); + mPasswordLabel = createLabel("Password"); + mCtrlPortLabel = createLabel("Ctrl Port"); + mCivPortLabel = createLabel("Civ Port"); + mAudioPortLabel = createLabel("Audio Port"); + + mRigNameEdit = new ExpandInput(); + mUserNameEdit = new ExpandInput(); + mPasswordEdit = new ExpandInput(); + mCtrlPortEdit = new ExpandInput(); + mCivPortEdit = new ExpandInput(); + mAudioPortEdit = new ExpandInput(); + + mainLayout->addLayout(createHBoxLayout({mRigNameLabel, mRigNameEdit}), 1); + mainLayout->addLayout(createHBoxLayout({mUserNameLabel, mUserNameEdit}), 1); + mainLayout->addLayout(createHBoxLayout({mPasswordLabel, mPasswordEdit}), 1); + mainLayout->addLayout(createHBoxLayout({mCtrlPortLabel, mCtrlPortEdit}), 1); + mainLayout->addLayout(createHBoxLayout({mCivPortLabel, mCivPortEdit}), 1); + mainLayout->addLayout(createHBoxLayout({mAudioPortLabel, mAudioPortEdit}), 1); + mShowHelpInfo = new ShowHelpInfo; + mShowHelpInfo->mFont.setPixelSize(40); + mainLayout->addWidget(mShowHelpInfo, 3); + int fontSize = 40; + mStartButton = createClickButton("Start", fontSize, [&]() { + mShowHelpInfo->setText("Start 帮助信息"); + mShowHelpInfo->update(); + }, &mRollObject); + mDefaultButton = createClickButton("Default", fontSize, [&]() { + mShowHelpInfo->setText("Default 帮助信息"); + mShowHelpInfo->update(); + }, &mRollObject); + mClearButton = createClickButton("Clear", fontSize, [&]() { + mShowHelpInfo->setText("Clear 帮助信息"); + mShowHelpInfo->update(); + }, &mRollObject); + mSaveButton = createClickButton("Save", fontSize, [&]() { + mShowHelpInfo->setText("Save 帮助信息"); + mShowHelpInfo->update(); + }, &mRollObject); + mExitButton = createClickButton("Exit", fontSize, [&]() { + MainWidget::instance()->hideCurHoverWidget(); + MainWidget::instance()->getCurrentBaseWidget()->setFocus(); + }, &mRollObject); + mRollObject.mWidgets = {mStartButton, mDefaultButton, mClearButton, mSaveButton, mExitButton}; + mRollObject.mEnterFunc = [](QPushButton* btn){ + btn->setChecked(true); + }; + mRollObject.mLeaveFunc = [](QPushButton* btn){ + btn->setChecked(false); + }; + mainLayout->addLayout(mRollObject.hBoxLayout(8), 2); +} + +void ServerSettingWidget::paintEvent(QPaintEvent *event) { + QPainter painter(this); + painter.setPen(Qt::NoPen); + QPalette palette = QApplication::style()->standardPalette(); + const QBrush& base1Brush = palette.brush(QPalette::Window); + painter.setBrush(base1Brush); + painter.drawRect(rect()); + painter.end(); +} + +QLabel *ServerSettingWidget::createLabel(const QString& text) { + auto ret = new QLabel(text); + QFont font; + font.setBold(true); + font.setPixelSize(Global::instance()->adaptHeight(50)); + ret->setFont(font); + QPalette pe; + pe.setColor(QPalette::WindowText, Qt::black); + ret->setPalette(pe); + return ret; +} + +void ServerSettingWidget::keyPressEvent(QKeyEvent *event) { + if (event->type() == QEvent::KeyPress) { + BackEnd* g = BackEnd::instance(); + auto *keyEvent = dynamic_cast(event); + if(g->match(keyEvent, "左移")){ + mRollObject.rollLeft(); + event->accept(); + return; + } + if(g->match(keyEvent, "右移")){ + mRollObject.rollRight(); + event->accept(); + return; + } + if(g->match(keyEvent, "确定")){ + mRollObject.cur()->emit clicked(); + event->accept(); + return; + } + } + event->ignore(); +} + +void ServerSettingWidget::showEvent(QShowEvent *event) { + mRollObject.mEnterFunc(mRollObject.cur()); + event->accept(); +} + + + diff --git a/module/radio/subWidget/ServerSettingWidget.h b/module/radio/subWidget/ServerSettingWidget.h new file mode 100644 index 0000000..baa1197 --- /dev/null +++ b/module/radio/subWidget/ServerSettingWidget.h @@ -0,0 +1,26 @@ +#ifndef ServerSettingWidget_H +#define ServerSettingWidget_H +#include "../Global.h" +#include "YSGraphic_Core/base/export.h" +class QLabel; +class QPushButton; +class ExpandInput; +class ShowHelpInfo; +class ServerSettingWidget : public QWidget { +public: + explicit ServerSettingWidget(QWidget *parent = nullptr); + QLabel *mRigNameLabel, *mUserNameLabel, *mPasswordLabel, *mCtrlPortLabel, *mCivPortLabel, *mAudioPortLabel; + ExpandInput *mRigNameEdit, *mUserNameEdit, *mPasswordEdit, *mCtrlPortEdit, *mCivPortEdit, *mAudioPortEdit; + ShowHelpInfo* mShowHelpInfo; + YSG::RollObject mRollObject; + QPushButton *mStartButton, *mDefaultButton, *mClearButton, *mSaveButton, *mExitButton; + static QLabel* createLabel(const QString& text); +protected: + void paintEvent(QPaintEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + void showEvent(QShowEvent *event) override; +}; +#endif + + + diff --git a/module/radio/todolist.txt b/module/radio/todolist.txt new file mode 100644 index 0000000..7ee760b --- /dev/null +++ b/module/radio/todolist.txt @@ -0,0 +1,7 @@ + + + + + + +余辉图添加修改线等单元测试 diff --git a/old_example/audio/MainWidget.cpp b/old_example/audio/MainWidget.cpp new file mode 100644 index 0000000..89418cf --- /dev/null +++ b/old_example/audio/MainWidget.cpp @@ -0,0 +1,143 @@ +#include "MainWidget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "core/AudioPlot.h" +#include "core/AudioAxis.h" +#include +#include +#include "core/AudioPlotData.h" +#include "core/AudioPlottable.h" +#include +#include + +QVBoxLayout* createVBoxLayout(const QVector& widgets) { + auto layout = new QVBoxLayout; + for (auto widget : widgets) { + layout->addWidget(widget); + } + return layout; +} + +QHBoxLayout* createHBoxLayout(const QVector& widgets) { + auto layout = new QHBoxLayout; + for (auto widget : widgets) { + layout->addWidget(widget); + } + return layout; +} + +MainWidget::MainWidget() { + auto layout = new QVBoxLayout; + setLayout(layout); + QAudioEncoderSettings audioSettings; + audioSettings.setCodec("audio/pcm"); // 使用PCM编码 + audioSettings.setSampleRate(44100); // 设置采样率 + audioSettings.setChannelCount(1); // 设置为单声道 + audioSettings.setQuality(QMultimedia::HighQuality); // 设置音质 + audioSettings.setEncodingMode(QMultimedia::ConstantBitRateEncoding); // 设置编码模式 + audioSettings.setBitRate(16); // 设置比特率 + QString container = "audio/wav"; + + mAudioPlot = new AudioPlot; + mAudioPlot->init(); + mAudioPlot->mObjectName = "AudioPlot"; + mAudioPlot->bindRenderThread("AudioPlotThread"); + + + connect(mAudioPlot, &AudioPlot::audioChanged, [this](Audio* oldAudio, Audio* newAudio) { + if(newAudio) { + QString filePath = newAudio->fullPath(); + if (!QFileInfo::exists(filePath)) { + qDebug() << "File does not exist:" << filePath; + return; + } + mPlayer->setMedia(QUrl::fromLocalFile(filePath)); + mPlayer->setVolume(50); + mPlayer->play(); + } + if(!newAudio && oldAudio) { + mPlayer->pause(); + } + }); + mPlayer = new QMediaPlayer; + { + mAudioPlotTimer = new QTimer(this); + mAudioPlotTimer->setTimerType(Qt::PreciseTimer); + + auto selectLine = new QHBoxLayout; + selectLine->addWidget(new QLabel("选择线:")); + mSelectLineIndex = new QComboBox; + int n = mAudioPlot->mAudioPlotData->mLines.size(); + for(int i = 0; i < n; ++i) { + mSelectLineIndex->addItem(QString::number(i)); + } + selectLine->addWidget(mSelectLineIndex); + + layout->addLayout(selectLine); + auto back = new QPushButton("回到起点"); + selectLine->addWidget(back); + connect(back, &QPushButton::clicked, [this]() { + mAudioPlot->xAxis->setAX(mAudioPlot->mAudioPlotData->startPixel() -mAudioPlot->width()); + mAudioPlot->update(); + }); + + + auto play = new QPushButton("播放"); + selectLine->addWidget(play); + connect(play, &QPushButton::clicked, [this]() { + mAudioPlot->mAudioPlotData->curLine = mAudioPlot->mAudioPlotData->mLines[mSelectLineIndex->currentText().toInt()]; + mAudioPlot->mAudioPlottable->setInit(); + mAudioPlotTimer->start(30); + }); + QObject::connect(mAudioPlotTimer, &QTimer::timeout, [this]() { + mAudioPlot->mAudioPlottable->move(mAudioPlotTimer->interval()); + mAudioPlot->update(); + if(mAudioPlot->mAudioPlottable->isStop()) { + mAudioPlotTimer->stop(); + } + }); + auto pause = new QPushButton("暂停"); + selectLine->addWidget(pause); + connect(pause, &QPushButton::clicked, [this]() { + mAudioPlotTimer->stop(); + }); + } + + { + auto selectTime = new QHBoxLayout; + selectTime->addWidget(new QLabel("输入返回的时间:")); + auto inputBackTime = new QLineEdit; + selectTime->addWidget(inputBackTime); + auto confirm = new QPushButton("确定"); + selectTime->addWidget(confirm); + layout->addLayout(selectTime); + connect(confirm, &QPushButton::clicked, [this, inputBackTime]() { + int milliseconds = inputBackTime->text().toInt(); + int pixel = mAudioPlot->xAxis->millisecondToPixel(milliseconds, YSG::SRC::Cache); + mAudioPlot->xAxis->setAX(pixel); + mAudioPlot->update(); + }); + } + layout->addWidget(mAudioPlot); + + + connect(mPlayer, &QMediaPlayer::durationChanged, [this](qint64 duration) { + if (mPlayer->error() != QMediaPlayer::NoError || duration < 1000) + return; + setWindowTitle(tr("Recorded %1 sec").arg(duration / 1000)); + }); + + connect(mPlayer, QOverload::of(&QMediaPlayer::error), + [this](QMediaPlayer::Error error) { + qDebug() << "Error occurred:" << mPlayer->errorString(); + + }); +} \ No newline at end of file diff --git a/old_example/audio/MainWidget.h b/old_example/audio/MainWidget.h new file mode 100644 index 0000000..9e02e65 --- /dev/null +++ b/old_example/audio/MainWidget.h @@ -0,0 +1,23 @@ +#ifndef MainWidget_H +#define MainWidget_H +#include + +class QLineEdit; +class QAudioRecorder; +class QPushButton; +class QComboBox; +class QMediaPlayer; +class AudioPlot; +class QAudioOutput; +class MainWidget : public QWidget { +public: + MainWidget(); + QTimer* mAudioPlotTimer; + AudioPlot *mAudioPlot{}; + QComboBox* mSelectLineIndex; + QMediaPlayer *mPlayer{}; +}; +#endif + + + diff --git a/old_example/audio/core/AudioAxis.cpp b/old_example/audio/core/AudioAxis.cpp new file mode 100644 index 0000000..fe10fcd --- /dev/null +++ b/old_example/audio/core/AudioAxis.cpp @@ -0,0 +1,82 @@ +#include "AudioAxis.h" +#include "AudioPlot.h" +#include "Axis/AbsAxis_p.h" +#include "RenderAble.h" +#include "AudioPlotData.h" + +double AudioAxis::millisecondToPixel(double millisecond, YSG::SRC src){ + if(mPlot->mAudioPlotData->mBlocks.empty()) return 0; + int blockIndex = Block::getMillisecondRange(millisecond, mPlot->mAudioPlotData->mBlocks); + Block* block = mPlot->mAudioPlotData->mBlocks[blockIndex]; + if(millisecond > block->mEndMillisecond) { + if(blockIndex == mPlot->mAudioPlotData->mBlocks.size() - 1) { + return block->endPixel(); + } + Block *block1 = block; + Block *block2 = mPlot->mAudioPlotData->mBlocks[blockIndex+1]; + double rate = mPlot->mAudioPlotData->comPressPixel / (block2->mStartMillisecond - block1->mEndMillisecond); + return block1->endPixel() + (millisecond - block1->mEndMillisecond) * rate; + } + if(millisecond < block->mStartMillisecond) { + if(blockIndex == 0) { + return block->startPixel(); + } + Block *block1 = mPlot->mAudioPlotData->mBlocks[blockIndex-1]; + Block *block2 = block; + double rate = mPlot->mAudioPlotData->comPressPixel / (block2->mStartMillisecond - block1->mEndMillisecond); + return block1->endPixel() + (millisecond - block1->mEndMillisecond) * rate; + } + double pixel = (millisecond - block->mStartMillisecond)/block->millisecondLength() * block->pixelLength() + block->startPixel(); + return pixel; +} + +double AudioAxis::pixelToMillisecond(double pixel, YSG::SRC src){ + if(mPlot->mAudioPlotData->mBlocks.empty()) return 0; + int blockIndex = Block::getPixelRange(pixel, mPlot->mAudioPlotData->mBlocks); + Block* block = mPlot->mAudioPlotData->mBlocks[blockIndex]; + double blockStartPixel = block->startPixel(), blockEndPixel = block->endPixel(); + if(pixel > blockEndPixel) { + if(blockIndex == mPlot->mAudioPlotData->mBlocks.size() - 1) { + return block->mEndMillisecond; + } + Block* block1 = block; + Block* block2 = mPlot->mAudioPlotData->mBlocks[blockIndex+1]; + double block1EndPixel = blockEndPixel; + double block2StartPixel = block2->startPixel(); + double rate = (block2->mStartMillisecond - block1->mEndMillisecond)/(block2StartPixel - block1EndPixel); + return block1->mEndMillisecond + (pixel - block1EndPixel) * rate; + } + if(pixel < blockStartPixel) { + if(blockIndex == 0) { + return block->mStartMillisecond; + } + Block* block1 = mPlot->mAudioPlotData->mBlocks[blockIndex-1]; + Block* block2 = block; + double block1EndPixel = block1->endPixel(); + double block2StartPixel = blockStartPixel; + double rate = (block2->mStartMillisecond - block1->mEndMillisecond)/(block2StartPixel - block1EndPixel); + return block1->mEndMillisecond + (pixel - block1EndPixel) * rate; + } + return (pixel - block->startPixel())/block->pixelLength() * block->millisecondLength() + block->mStartMillisecond; +} + +double AudioAxis::showPixelToPixel(double showPixel, YSG::SRC src) { + return showPixel + ax(src); +} + +double AudioAxis::pixelToShowPixel(double pixel, YSG::SRC src){ + return pixel - ax(src); +} + +double AudioAxis::showPixelToMillisecond(double showPixel, YSG::SRC src){ + return pixelToMillisecond(showPixelToPixel(showPixel, src), src); +} + +double AudioAxis::millisecondToShowPixel(double millisecond, YSG::SRC src){ + return pixelToShowPixel(millisecondToPixel(millisecond, src), src); +} + + + + + diff --git a/old_example/audio/core/AudioAxis.h b/old_example/audio/core/AudioAxis.h new file mode 100644 index 0000000..08be58e --- /dev/null +++ b/old_example/audio/core/AudioAxis.h @@ -0,0 +1,81 @@ +#ifndef AudioAxis_H +#define AudioAxis_H +#include + +#include "Axis/AbsAxis.h" +#include "AudioGlobalTypes.h" + + +class AudioPlot; +struct AudioAxisPrivate; +struct AudioAxisData { + // mX代表着 view视图在 总体场景下的坐标 + double mX = 0; +}; + +class AudioAxis : public YSG::Axis { +public: + AudioPlot* mPlot{}; + QVector mBlocks; + YSG::CacheModel mModel; + + double ax(YSG::SRC src) { + return mModel.getState(src)->mX; + } + void setAX(double x) { + YSG::SpinLockGuard g(&mModel.mLock); + mModel.cache.mX = x; + } + + void prepareData() override { + Axis::prepareData(); + { + YSG::SpinLockGuard g (&mModel.mLock); + mModel.loadCache(); + } + } + + [[nodiscard]] double showPixelToMillisecond(double showPixel, YSG::SRC src); + [[nodiscard]] double millisecondToShowPixel(double millisecond, YSG::SRC src); + [[nodiscard]] double millisecondToPixel(double millisecond, YSG::SRC src); + [[nodiscard]] double pixelToMillisecond(double pixel, YSG::SRC src); + [[nodiscard]] double showPixelToPixel(double showPixel, YSG::SRC src); + [[nodiscard]] double pixelToShowPixel(double pixel, YSG::SRC src); + + void init(YSG::Plot* plot, QString layerName) override { + YSG::Axis::init(plot, layerName); + set_numberPrecision(0); + set_rotate(-60); + } + + QVector createSubTickVector(int subTickCount, const QVector &ticks, const YSG::Range& range) override { + return {}; + } + + QVector createTickVector(double tickStep, const YSG::Range &range) override { + QVector ret; + for(Block* block : mBlocks) { + //auto c = Axis::createTickVector(tickStep, {block->start, block->start + block->len}); + ret.append(block->mEndMillisecond); + ret.append(block->mStartMillisecond); + for(Audio* audio : block->audios) { + ret.append((audio->mStartMillisecond + audio->mEndMillisecond)/2); + } + } + return ret; + } + + [[nodiscard]] double pixelToCoord(double value, YSG::SRC src) override { + return showPixelToMillisecond(value, src); + } + [[nodiscard]] double coordToPixel(double value, YSG::SRC src) override { + return millisecondToShowPixel(value, src); + } +}; + + + + + + +#endif \ No newline at end of file diff --git a/old_example/audio/core/AudioGlobalTypes.h b/old_example/audio/core/AudioGlobalTypes.h new file mode 100644 index 0000000..6176282 --- /dev/null +++ b/old_example/audio/core/AudioGlobalTypes.h @@ -0,0 +1,119 @@ +#ifndef GlobalTypes_H +#define GlobalTypes_H +#include +#include +#include +#include +#include +#include +#include +#include "export.h" + +namespace YSG { + class Axis; +} +class AudioAxis; +struct AudioPlotData; +class AudioPlottable; +class AudioPlot; +struct MillisecondRange { + double mStartMillisecond{}; + double mEndMillisecond{}; + [[nodiscard]] double millisecondLength() const {return mEndMillisecond - mStartMillisecond;} +}; + +// struct PixelRange { +// double mStartPixel{}; +// double mEndPixel{}; +// [[nodiscard]] double pixelLength() const {return mEndPixel - mStartPixel;}; +// }; + +class Line; + +struct Audio; +// 传来有序的内容 +struct Block : MillisecondRange { + int mSpaceNum = 0; + + double mPreviousMillisecond{}; + double mSpaceLength{}; + + double prev, next; //prev 加上前置的上界, 加上前置的下界 + MillisecondRange prevSpace() {return {prev, mStartMillisecond};} + MillisecondRange nextSpace() {return {mStartMillisecond + millisecondLength(), next};} + QVector audios; + int index = 0; + AudioPlotData *mData{}; + QString toString(); + + double startPixel(); + double endPixel(); + double pixelLength(); + + static int getPixelRange(double value, const QVector& blocks){ + static std::function lower = [](Block* b) {return b->startPixel();}; + static std::function upper = [](Block* b) {return b->endPixel();}; + return YSG::binary_search(value, const_cast(blocks.data()), blocks.size(), lower, upper); + } + static int getMillisecondRange(double value, const QVector& blocks) { + static std::function lower = [](Block* b) {return b->mStartMillisecond;}; + static std::function upper = [](Block* b) {return b->mEndMillisecond;}; + return YSG::binary_search(value, const_cast(blocks.data()), blocks.size(), lower, upper); + } +}; + +struct Audio : MillisecondRange { + double value{}; + QString fullPath(); + [[nodiscard]] QString toString() const { + return QString("startMillisecond: %1, endMillisecond: %2 fileName: %3") + .arg(mStartMillisecond).arg(mEndMillisecond) + .arg(mFileName); + } + Line *mLine{}; + Block *mBlock{}; + double startPixel(); + double endPixel(); + double pixelLength(); + QString mFileName; + Audio(double startMillisecond, double endMillisecond, double value = 5, const QString& fileName = "") { + mStartMillisecond = startMillisecond; + mEndMillisecond = endMillisecond; + mFileName = fileName; + this->value = value; + } +}; + + +struct Line { + QVector audios; + double tail = std::numeric_limits::lowest(); + double lower(int index, double start); + double upper(int index, double end); + YSG::Axis *mAxis{}; + QString toString(); + int getAudio(double pixel) { + static std::function lower = [](Audio* b) {return b->startPixel();}; + static std::function upper = [](Audio* b) {return b->endPixel();}; + return YSG::binary_search