类图结构如下:
整个框架只需要继承想要的基类,编写好qss文件就可以了,如上的效果实现代码如下:分别为.h、.cpp、.qss代码
1 #pragma once 2 #include "CMenuBar.h" 3 #include "CToolBar.h" 4 #include "CTitleWidget.h" 5 #include "CStatusWidget.h" 6 #include "CMainWindowBase.h" 7 8 class MainMenuBar : public MenuBar 9 { 10 Q_OBJECT 11 public: 12 MainMenuBar(QWidget* parent = Q_NULLPTR) : MenuBar(parent) { 13 Init(); 14 } 15 ~MainMenuBar() {} 16 17 protected: 18 void Init(); 19 20 public: 21 //数据 22 QAction* subscribe;//订阅设置 23 QAction* recive;//开始接收 24 QAction* sync_tick;//同步tick 25 QAction* sync_kline;//同步k线 26 27 //回测 28 QAction* hc_cpp/*c++策略*/; 29 }; 30 31 class TitleWindow : public TitleWidget 32 { 33 Q_OBJECT 34 public: 35 TitleWindow(QWidget* parent); 36 37 void Init() override; 38 39 40 public: 41 MainMenuBar* menu_bar; 42 }; 43 44 class MainToolBar : public ToolBar 45 { 46 Q_OBJECT 47 public: 48 MainToolBar(QWidget* parent = Q_NULLPTR) : ToolBar(parent) { 49 Init(); 50 } 51 ~MainToolBar() {} 52 53 protected: 54 void Init(); 55 }; 56 57 class MainStatus : public StatusWidget 58 { 59 Q_OBJECT 60 public: 61 MainStatus(QWidget* parent = Q_NULLPTR) : StatusWidget(parent) { Init(); } 62 ~MainStatus() {} 63 64 void Init() override; 65 66 protected slots: 67 void OnServerStatus(bool); 68 void OnCtpStatus(bool); 69 70 public: 71 QLabel* label_server, *label_ctp;//服务器、ctp连接状态 72 }; 73 74 class MainWidowEntity : public MainWindowImpl 75 { 76 public: 77 MainWidowEntity(QWidget* parent = Q_NULLPTR); 78 ~MainWidowEntity(); 79 80 void InitWindow() override; 81 void InitSignal() override; 82 }; 83 84 class MainWindow : public MainWindowBase 85 { 86 public: 87 MainWindow(); 88 ~MainWindow(); 89 90 MainWindowImpl* CreateImpl(); 91 };
1 #include "MainWindow.h" 2 #include "CStatusWidget.h" 3 #include <QMenuBar> 4 #include <QToolBar> 5 #include <QButtonGroup> 6 7 void MainMenuBar::Init() 8 { 9 QMenu* menu_system = new QMenu(u8"系统"); 10 QAction* system_setting = make_name<QAction>("system_setting"); 11 system_setting->setText(u8"设置"); 12 menu_system->addAction(system_setting); 13 14 QMenu* menu_data = new QMenu(u8"数据"); 15 QMenu* menu_realtime = menu_data->addMenu(u8"实时数据"); 16 menu_realtime->addAction(subscribe = make_name<QAction>("subscribe", u8"订阅设置")); 17 menu_realtime->addAction(recive = make_name<QAction>("recive", u8"开始|停止接收")); 18 QMenu* menu_history = menu_data->addMenu(u8"历史数据"); 19 menu_history->addAction(sync_tick = make_name<QAction>("sync_tick", u8"同步tick")); 20 menu_history->addAction(sync_kline = make_name<QAction>("sync_kline", u8"同步k线")); 21 QMenu* menu_analyze = new QMenu(u8"分析"); 22 QMenu* menu_backtest = new QMenu(u8"回测"); 23 QMenu* menu_trade = new QMenu(u8"交易"); 24 25 AddMenu({ menu_system, menu_data, menu_analyze, menu_backtest, menu_trade }); 26 CalcGeometry(); 27 } 28 29 ////////////////////////////////////////////////////////////////////////// 30 TitleWindow::TitleWindow(QWidget* parent) : TitleWidget(parent) { 31 Init(); 32 } 33 34 void TitleWindow::Init() 35 { 36 TitleWidget::Init(); 37 menu_bar = new MainMenuBar(); 38 InsertWidget(0, menu_bar); 39 } 40 41 ////////////////////////////////////////////////////////////////////////// 42 43 44 void MainToolBar::Init() 45 { 46 //主面板操作按钮 47 AddToolButton(make_name<QToolButton>("back")); 48 AddToolButton(make_name<QToolButton>("ahead")); 49 AddSeparator(); 50 //周期按钮 51 QButtonGroup* group_cycle = new QButtonGroup(this); 52 group_cycle->setExclusive(true);//设置互斥 53 group_cycle->addButton(make_name<QToolButton>("1m"), 0); 54 group_cycle->addButton(make_name<QToolButton>("3m"), 1); 55 group_cycle->addButton(make_name<QToolButton>("5m"), 2); 56 group_cycle->addButton(make_name<QToolButton>("nm"), 3); 57 group_cycle->addButton(make_name<QToolButton>("1d"), 4); 58 AddToolButton((QToolButton*)group_cycle->button(0), true); 59 AddToolButton((QToolButton*)group_cycle->button(1), true); 60 AddToolButton((QToolButton*)group_cycle->button(2), true); 61 AddToolButton((QToolButton*)group_cycle->button(3), true); 62 AddToolButton((QToolButton*)group_cycle->button(4), true); 63 //((QToolButton*)group_cycle->button(1))->setChecked(true); 64 AddSeparator(); 65 } 66 67 ////////////////////////////////////////////////////////////////////////// 68 void MainStatus::Init() 69 { 70 QHBoxLayout* layout_ = make_layout<QHBoxLayout>(); 71 layout_->setContentsMargins(10, 0, 0, 10); 72 layout_->setSpacing(2); 73 layout_->addWidget(status); 74 } 75 76 void MainStatus::OnServerStatus(bool b) 77 { 78 79 } 80 81 void MainStatus::OnCtpStatus(bool b) 82 { 83 84 } 85 86 ////////////////////////////////////////////////////////////////////////// 87 MainWidowEntity::MainWidowEntity(QWidget * parent) : MainWindowImpl(parent) 88 { 89 } 90 91 MainWidowEntity::~MainWidowEntity() 92 { 93 94 } 95 96 void MainWidowEntity::InitWindow() 97 { 98 title = new TitleWindow(this); 99 toolbar = new MainToolBar(this); 100 101 body = new StyleWidget(this); 102 body->setObjectName("body"); 103 104 status = new MainStatus(this); 105 layout()->addWidget(title); 106 layout()->addWidget(toolbar); 107 layout()->addWidget(body); 108 layout()->addWidget(status); 109 InitSignal(); 110 } 111 112 #include "DlgSyncTick.h" 113 #define TITLE_WINDOW (qobject_cast<TitleWindow*>(title)) 114 void MainWidowEntity::InitSignal() 115 { 116 MainWindowImpl::InitSignal(); 117 connect(TITLE_WINDOW->menu_bar->subscribe, &QAction::triggered, this, []() {}); 118 connect(TITLE_WINDOW->menu_bar->recive, &QAction::triggered, this, []() {}); 119 connect(TITLE_WINDOW->menu_bar->sync_tick, &QAction::triggered, this, [this]() { 120 DlgSyncTick* dlg = new DlgSyncTick(); 121 dlg->show(); 122 }); 123 connect(TITLE_WINDOW->menu_bar->sync_kline, &QAction::triggered, this, []() {}); 124 } 125 126 ////////////////////////////////////////////////////////////////////////// 127 MainWindow::MainWindow() 128 { 129 } 130 131 132 MainWindow::~MainWindow() 133 { 134 } 135 136 MainWindowImpl* MainWindow::CreateImpl() 137 { 138 return new MainWidowEntity(this); 139 }
/*标题栏*/ TitleWidget { min-height: 25px; max-height: 25px; background: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #e5e5e5, stop:0.3 #F4F4F4, stop:1 #cacaca); } TitleWidget QToolButton { min-height: 20px; max-height: 20px; } MainMenuBar QMenuBar { background: transparent; } MainMenuBar QMenuBar::item { background: transparent; } /* 最小化按钮 */ QToolButton#button_min { min-width: 23px; max-width: 23px; border-image: url(:/skin/MainWindow/minnormal.bmp) 0 3 24 1; } /* 最大化按钮 */ QToolButton#button_max[status="0"] { min-width: 22px; max-width: 22px; border-image: url(:/skin/MainWindow/maxnormal.bmp) 0 1 24 1; } /* 还原按钮 */ QToolButton#button_max[status="1"] { min-width: 22px; max-width: 22px; border-image: url(:/skin/MainWindow/restorenormal.bmp) 0 1 24 1; } /* 关闭按钮 */ QToolButton#button_close { min-width: 32px; max-width: 32px; border-image: url(:/skin/MainWindow/closenormal.bmp) 0 1 24 1; } QToolButton#button_close:hover { border-image: url(:/skin/MainWindow/closenormal.bmp) 0 1 24 1; } QToolButton#button_close:pressed { border-image: url(:/skin/MainWindow/closenormal.bmp) 0 1 24 1; } /* 工具栏 */ MainToolBar { min-height: 30px; max-height: 30px; background-color: rgb(235,235,235); } QToolBar { min-height:24px; max-height:24px; spacing:4px; } MainToolBar QToolButton { min-height: 22px; max-height: 22px; min-width: 22px; max-width: 22px; } MainToolBar QToolButton:hover,QToolButton:checked { border:1px solid black; border-radius:4px; padding:4px; } /*top,right,bottom,left*/ QToolButton#back { background: url(:/skin/MainWindow/toolbar/back.png) no-repeat center; } QToolButton#ahead { background: url(:/skin/MainWindow/toolbar/ahead.png) no-repeat center; } QToolButton#1m { background: url(:/skin/MainWindow/toolbar/1m.png) no-repeat center; } QToolButton#3m { background: url(:/skin/MainWindow/toolbar/3m.png) no-repeat center; } QToolButton#5m { background: url(:/skin/MainWindow/toolbar/5m.png) no-repeat center; } QToolButton#nm { background: url(:/skin/MainWindow/toolbar/nm.png) no-repeat center; } QToolButton#1d { background: url(:/skin/MainWindow/toolbar/1d.png) no-repeat center; } /*主体*/ StyleWidget#body { background-color: rgb(10,10,10); } /*状态栏*/ StatusWidget { min-height: 25px; max-height: 25px; background: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #e5e5e5, stop:0.4 #e8e8e8, stop:1 #cacaca); }
实现简单的对话框也很容易:
1 #pragma once 2 #include "CDialog.h" 3 #include "CToolBar.h" 4 #include "CTitleWidget.h" 5 6 class TitleBar : public TitleWidget 7 { 8 Q_OBJECT 9 public: 10 TitleBar(QWidget* parent = Q_NULLPTR) : TitleWidget(parent) {} 11 void Init() { 12 btns[button_min] = make_name<StatusToolButton>("button_min"); 13 btns[button_close] = make_name<StatusToolButton>("button_close"); 14 QHBoxLayout* layout_ = make_layout<QHBoxLayout>(); 15 layout_->addStretch(); 16 layout_->addWidget(btns[button_min], 0, Qt::AlignTop); 17 layout_->addWidget(btns[button_close], 0, Qt::AlignTop); 18 setLayout(layout_); 19 title = new QLabel(u8"软件标题"); 20 InsertWidget(0, title, 1, Qt::AlignCenter); 21 connect(btns[button_min], &QToolButton::clicked, [&]() { 22 emit buttonClick(btns[button_min]); 23 }); 24 connect(btns[button_close], &QToolButton::clicked, [&]() { 25 emit buttonClick(btns[button_close]); 26 }); 27 } 28 }; 29 30 class StatusBar : public ToolBar 31 { 32 Q_OBJECT 33 public: 34 StatusBar(QWidget* parent = Q_NULLPTR) : ToolBar(parent) {} 35 36 void Init() 37 { 38 AddToolButton(make_name<QToolButton>("trade")); 39 AddToolButton(make_name<QToolButton>("market")); 40 AddSeparator(); 41 } 42 43 public: 44 QToolButton* btn_trade, *btn_market; 45 }; 46 47 class ManualTrade : public Dialog 48 { 49 Q_OBJECT 50 51 public: 52 ManualTrade(QWidget *parent = Q_NULLPTR); 53 54 public: 55 void Init(); 56 57 private: 58 };
1 #include "ManualTrade.h" 2 3 ManualTrade::ManualTrade(QWidget *parent) 4 : Dialog(parent) 5 { 6 7 } 8 9 void ManualTrade::Init() 10 { 11 Dialog::Init(new TitleBar(this), nullptr, new StatusBar(this)); 12 layout->addWidget(status_bar); 13 14 SetTitle(u8"<span style='color:#9E0404'>期海捕鱼</span>"); 15 }
以上全是个人兴趣写的,暂时满足了我对windows软件漂亮UI的需求。