diff --git a/Static/Main.qss b/Static/Main.qss index 87a6dc0..9587b6f 100644 --- a/Static/Main.qss +++ b/Static/Main.qss @@ -20,13 +20,16 @@ QWidget#topWidget { background-color: #2277EF; } -QWidget#userWidget, QWidget#varWidget, QWidget#projectWidget, QWidget#trendWidget, QWidget#LoginWidget { +QWidget#userWidget, +QWidget#projectWidget, +QWidget#LoginWidget { background-color: #FFFFFF; border-radius: 8px; border: 1px solid #E5E7EB; } -QWidget#userBtnWidget, QWidget#projectBtnWidget { +QWidget#userBtnWidget, +QWidget#projectBtnWidget { background-color: #FFFFFF; margin-top: 7px; margin-right: 7px; @@ -43,21 +46,26 @@ QWidget#registerWidget { /* ==================== 左侧导航栏样式 ==================== */ QWidget#leftWidget { - background: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #FFFFFF, - stop:0.2 #FEFEFE, - stop:0.5 #FAFBFC, - stop:0.8 #F6F8FA, - stop:1 #F1F3F5); + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #FFFFFF, + stop:0.2 #FEFEFE, + stop:0.5 #FAFBFC, + stop:0.8 #F6F8FA, + stop:1 #F1F3F5); border-right: 1px solid #E1E5E9; min-width: 260px; max-width: 260px; } /* 导航按钮基础样式 */ -QPushButton#createProject, QPushButton#openProject, QPushButton#trendMag, -QPushButton#varMag, QPushButton#userMag, QPushButton#protocolMag, -QPushButton#controlMag, QPushButton#procedureMag { +QPushButton#createProject, +QPushButton#openProject, +QPushButton#userMag, +QPushButton#protocolMag, +QPushButton#controlMag, +QPushButton#procedureMag, +QPushButton#varMag, +QPushButton#trendMag { border: none; font-size: 16px; text-align: left; @@ -72,25 +80,35 @@ QPushButton#controlMag, QPushButton#procedureMag { } /* 导航按钮悬停效果 */ -QPushButton#createProject:hover, QPushButton#openProject:hover, QPushButton#trendMag:hover, -QPushButton#varMag:hover, QPushButton#userMag:hover, QPushButton#protocolMag:hover, -QPushButton#controlMag:hover, QPushButton#procedureMag:hover { +QPushButton#createProject:hover, +QPushButton#openProject:hover, +QPushButton#userMag:hover, +QPushButton#protocolMag:hover, +QPushButton#controlMag:hover, +QPushButton#procedureMag:hover, +QPushButton#varMag:hover, +QPushButton#trendMag:hover { color: #2277EF; - background: qlineargradient(x1:0, y1:0, x2:1, y2:0, - stop:0 rgba(34, 119, 239, 15), - stop:1 rgba(34, 119, 239, 5)); + background: qlineargradient(x1:0, y1:0, x2:1, y2:0, + stop:0 rgba(34, 119, 239, 15), + stop:1 rgba(34, 119, 239, 5)); border-radius: 12px; } /* 导航按钮选中状态 */ -QPushButton#createProject:checked, QPushButton#openProject:checked, QPushButton#trendMag:checked, -QPushButton#varMag:checked, QPushButton#userMag:checked, QPushButton#protocolMag:checked, -QPushButton#controlMag:checked, QPushButton#procedureMag:checked { - background: qlineargradient(x1:0, y1:0, x2:1, y2:0, - stop:0 #2277EF, - stop:0.3 #3B82F6, - stop:0.7 #60A5FA, - stop:1 rgba(96, 165, 250, 200)); +QPushButton#createProject:checked, +QPushButton#openProject:checked, +QPushButton#userMag:checked, +QPushButton#protocolMag:checked, +QPushButton#controlMag:checked, +QPushButton#procedureMag:checked, +QPushButton#varMag:checked, +QPushButton#trendMag:checked { + background: qlineargradient(x1:0, y1:0, x2:1, y2:0, + stop:0 #2277EF, + stop:0.3 #3B82F6, + stop:0.7 #60A5FA, + stop:1 rgba(96, 165, 250, 200)); color: #FFFFFF; font-weight: bold; border-radius: 12px; @@ -104,7 +122,6 @@ QTableView { outline: none; gridline-color: transparent; background-color: #FFFFFF; - /* selection-background-color: #E3F2FD; */ selection-color: #1976D2; font-size: 15px; font-family: "PingFangSC-Regular", "Microsoft YaHei", sans-serif; @@ -122,49 +139,34 @@ QTableView::item { /* 表格项悬停效果 */ QTableView::item:hover { - /* background-color: #F8F9FA; */ color: #2277EF; } /* 表格项选中效果 */ QTableView::item:selected { - /* background-color: #E3F2FD; */ color: #1976D2; font-weight: 500; } /* ==================== 专用表格样式 ==================== */ /* 用户和工程表格特殊样式 */ -QTableView#userView, QTableView#projectView { +QTableView#userView, +QTableView#projectView { background-color: #FFFFFF; padding: 10px; } -QTableView#userView::item, QTableView#projectView::item { - /* background-color: #FFFFFF; */ - margin: 4px 2px; +QTableView#userView::item, +QTableView#projectView::item { + /* margin: 4px 2px; */ border-radius: 6px; - min-height: 56px !important; - height: 56px; - padding: 8px 14px; + min-height: 40px !important; + height: 40px; + /* padding: 8px 14px; */ font-size: 15px; line-height: 24px; } -/* 变量表格样式 */ -QTableView#varView { - background-color: #FFFFFF; - font-size: 16px; -} - -QTableView#varView::item { - margin: 0px; - border-radius: 0px; - min-height: 46px; - padding: 8px 12px; - /* 不设置background-color,让模型的背景颜色生效 */ -} - /* ==================== 表头统一样式 ==================== */ /* 表头基础样式 */ QHeaderView { @@ -182,34 +184,18 @@ QHeaderView::section { } /* 用户和工程表头样式 */ -QHeaderView#userHeader::section, QHeaderView#projectHeader::section { +QHeaderView#userHeader::section, +QHeaderView#projectHeader::section { color: #1F2937; font-size: 16px; height: 26px; - background: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #FFFFFF, - stop:1 #F8F9FA); + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #FFFFFF, + stop:1 #F8F9FA); padding: 16px 12px; border-bottom: 2px solid #E5E7EB; } -/* 变量表头样式 */ -QHeaderView::section { - color: #FFFFFF; - font-size: 16px; - height: 26px; - background-color: #4A5568; - padding: 12px 8px; -} - -QHeaderView#paramHeader::section { - color: #FFFFFF; - font-size: 15px; - height: 26px; - background-color: #4A5568; - padding: 10px 8px; -} - /* ==================== 按钮统一样式 ==================== */ /* 基础按钮样式 */ QPushButton { @@ -221,9 +207,9 @@ QPushButton { /* 设置按钮样式 */ QPushButton#setButton { min-height: 36px; - background: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #2277EF, - stop:1 #1976D2); + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #2277EF, + stop:1 #1976D2); border-radius: 6px; color: #FFFFFF; font-size: 14px; @@ -232,53 +218,249 @@ QPushButton#setButton { } QPushButton#setButton:hover { - background: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #3B82F6, - stop:1 #2277EF); + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #3B82F6, + stop:1 #2277EF); } QPushButton#setButton:pressed { - background: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #1976D2, - stop:1 #1565C0); + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #1976D2, + stop:1 #1565C0); } /* 功能按钮样式 */ -QPushButton#forceBtn, QPushButton#exportBtn, QPushButton#importBtn, -QPushButton#createBtn, QPushButton#delBtn, QPushButton#messageBtn, -QPushButton#startProtocolBtn, QPushButton#clearBtn { - color: #2277EF; - font-size: 14px; - font-weight: 500; - padding: 6px 12px; - background-color: transparent; - border-radius: 4px; +/* 新建按钮样式 */ +QPushButton#createBtn { + color: #1D4ED8; + font-size: 15px; + font-weight: 600; + padding: 8px 16px; + background-color: #EBF8FF; + border-radius: 6px; + border: 1px solid #BFDBFE; + font-family: "PingFangSC-Medium", "Microsoft YaHei", sans-serif; } -QPushButton#forceBtn:hover, QPushButton#exportBtn:hover, QPushButton#importBtn:hover, -QPushButton#createBtn:hover, QPushButton#delBtn:hover, QPushButton#messageBtn:hover, -QPushButton#startProtocolBtn:hover, QPushButton#clearBtn:hover { - background-color: #E3F2FD; +QPushButton#createBtn:hover { + background-color: #DBEAFE; + border-color: #93C5FD; + color: #1E40AF; +} + +QPushButton#createBtn:pressed { + background-color: #BFDBFE; + border-color: #60A5FA; + color: #1E3A8A; +} + +/* 导入按钮样式 */ +QPushButton#importBtn { + color: #047857; + font-size: 15px; + font-weight: 600; + padding: 8px 16px; + background-color: #ECFDF5; + border-radius: 6px; + border: 1px solid #BBF7D0; + font-family: "PingFangSC-Medium", "Microsoft YaHei", sans-serif; +} + +QPushButton#importBtn:hover { + background-color: #D1FAE5; + border-color: #86EFAC; + color: #065F46; +} + +QPushButton#importBtn:pressed { + background-color: #A7F3D0; + border-color: #6EE7B7; + color: #064E3B; +} + +/* 导出按钮样式 */ +QPushButton#exportBtn { + color: #6D28D9; + font-size: 15px; + font-weight: 600; + padding: 8px 16px; + background-color: #F3E8FF; + border-radius: 6px; + border: 1px solid #C4B5FD; + font-family: "PingFangSC-Medium", "Microsoft YaHei", sans-serif; +} + +QPushButton#exportBtn:hover { + background-color: #EDE9FE; + border-color: #A78BFA; + color: #5B21B6; +} + +QPushButton#exportBtn:pressed { + background-color: #DDD6FE; + border-color: #8B5CF6; + color: #4C1D95; +} + +/* 批量强制按钮样式 */ +QPushButton#forceBtn { + color: #D97706; + font-size: 15px; + font-weight: 600; + padding: 8px 16px; + background-color: #FEF3C7; + border-radius: 6px; + border: 1px solid #FCD34D; + font-family: "PingFangSC-Medium", "Microsoft YaHei", sans-serif; +} + +QPushButton#forceBtn:hover { + background-color: #FDE68A; + border-color: #FBBF24; + color: #B45309; +} + +QPushButton#forceBtn:pressed { + background-color: #FCD34D; + border-color: #F59E0B; + color: #92400E; +} + +/* 清除颜色按钮样式 */ +QPushButton#clearBtn { + color: #B91C1C; + font-size: 15px; + font-weight: 600; + padding: 8px 16px; + background-color: #FEF2F2; + border-radius: 6px; + border: 1px solid #FECACA; + font-family: "PingFangSC-Medium", "Microsoft YaHei", sans-serif; +} + +QPushButton#clearBtn:hover { + background-color: #FEE2E2; + border-color: #FCA5A5; + color: #991B1B; +} + +QPushButton#clearBtn:pressed { + background-color: #FECACA; + border-color: #F87171; + color: #7F1D1D; +} + +/* 查看报文按钮样式 */ +QPushButton#messageBtn { + color: #7C3AED; + font-size: 15px; + font-weight: 600; + padding: 8px 16px; + background-color: #F3E8FF; + border-radius: 6px; + border: 1px solid #C4B5FD; + font-family: "PingFangSC-Medium", "Microsoft YaHei", sans-serif; +} + +QPushButton#messageBtn:hover { + background-color: #EDE9FE; + border-color: #A78BFA; + color: #6D28D9; +} + +QPushButton#messageBtn:pressed { + background-color: #DDD6FE; + border-color: #8B5CF6; + color: #5B21B6; +} + +/* 开始通讯按钮样式 */ +QPushButton#startProtocolBtn { + color: #047857; + font-size: 15px; + font-weight: 600; + padding: 8px 16px; + background-color: #ECFDF5; + border-radius: 6px; + border: 1px solid #BBF7D0; + font-family: "PingFangSC-Medium", "Microsoft YaHei", sans-serif; +} + +QPushButton#startProtocolBtn:hover { + background-color: #D1FAE5; + border-color: #86EFAC; + color: #065F46; +} + +QPushButton#startProtocolBtn:pressed { + background-color: #A7F3D0; + border-color: #6EE7B7; + color: #064E3B; +} + +/* 批量删除按钮样式 */ +QPushButton#delBtn { + color: #B91C1C; + font-size: 15px; font-weight: 600; + padding: 8px 16px; + background-color: #FEF2F2; + border-radius: 6px; + border: 1px solid #FECACA; + font-family: "PingFangSC-Medium", "Microsoft YaHei", sans-serif; +} + +QPushButton#delBtn:hover { + background-color: #FEE2E2; + border-color: #FCA5A5; + color: #991B1B; +} + +QPushButton#delBtn:pressed { + background-color: #FECACA; + border-color: #F87171; + color: #7F1D1D; } /* 登录按钮样式 */ -QPushButton#loginButton, QPushButton#exitButton { - width: 80px; - height: 36px; - background: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #2277EF, - stop:1 #1976D2); +QPushButton#loginButton, +QPushButton#exitButton { + min-width: 80px; + min-height: 36px; + max-width: 120px; + max-height: 36px; + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #2277EF, + stop:1 #1976D2); + border: 1px solid #1976D2; border-radius: 6px; color: #FFFFFF; font-size: 14px; font-weight: 600; + font-family: "PingFangSC-Medium", "Microsoft YaHei", sans-serif; + padding: 8px 16px; +} + +QPushButton#loginButton:hover, +QPushButton#exitButton:hover { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #3B82F6, + stop:1 #2277EF); + border-color: #2277EF; +} + +QPushButton#loginButton:pressed, +QPushButton#exitButton:pressed { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #1976D2, + stop:1 #1565C0); + border-color: #1565C0; } -QPushButton#loginButton:hover, QPushButton#exitButton:hover { - background: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #3B82F6, - stop:1 #2277EF); +QPushButton#loginButton:focus, +QPushButton#exitButton:focus { + outline: none; + border: 2px solid #60A5FA; } /* ==================== 输入框统一样式 ==================== */ @@ -298,15 +480,9 @@ QLineEdit:focus { background-color: #F8F9FF; } -/* 设置输入框样式 */ -QLineEdit#setEdit { - min-width: 180px; - min-height: 32px; - font-size: 14px; -} - /* 用户输入框样式 */ -QLineEdit#userEdit, QLineEdit#pwdEdit { +QLineEdit#userEdit, +QLineEdit#pwdEdit { width: 240px; height: 36px; background-color: #F9FAFB; @@ -337,7 +513,7 @@ QLabel#titleLabel { } /* 设置标签样式 */ -QLabel#setlabel, QLabel#mesLabel { +QLabel#mesLabel { background-color: #F3F4F6; border: none; min-width: 180px; @@ -349,22 +525,8 @@ QLabel#setlabel, QLabel#mesLabel { font-weight: 500; } -/* TCP/RTU标签样式 */ -QLabel#tcpLable, QLabel#rtuLable { - background-color: #F3F4F6; - border: none; - width: 200px; - height: 40px; - border-radius: 6px; - padding: 8px 12px; - color: #374151; - font-size: 16px; - font-weight: 500; -} - /* ==================== 下拉框统一样式 ==================== */ QComboBox { - /* border: 1px solid #D1D5DB; */ border-radius: 6px; padding: 6px 12px; font-size: 14px; @@ -393,7 +555,7 @@ QComboBox::down-arrow { QComboBox QAbstractItemView { border: 1px solid #E5E7EB; - border-radius: 6px; + /* border-radius: 6px; */ background-color: #FFFFFF; selection-background-color: #E3F2FD; selection-color: #1976D2; @@ -410,6 +572,37 @@ QComboBox QAbstractItemView::item:hover { background-color: #F3F4F6; } +/* 全局下拉列表样式 - 强制修复黑色背景问题 */ +QComboBox QAbstractItemView { + background-color: white !important; + color: black !important; + border: 1px solid #E5E7EB; + /* border-radius: 4px; */ + selection-background-color: #E3F2FD !important; + selection-color: #1976D2 !important; + outline: none; + font-size: 14px; + show-decoration-selected: 1; +} + +QComboBox QAbstractItemView::item { + background-color: white !important; + color: black !important; + padding: 8px 12px; + min-height: 28px; + border: none; +} + +QComboBox QAbstractItemView::item:hover { + background-color: #F3F4F6 !important; + color: black !important; +} + +QComboBox QAbstractItemView::item:selected { + background-color: #E3F2FD !important; + color: #1976D2 !important; +} + /* ==================== 滚动条统一样式 ==================== */ QScrollBar:vertical { background: #F3F4F6; @@ -428,11 +621,13 @@ QScrollBar::handle:vertical:hover { background: #6B7280; } -QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical { +QScrollBar::add-line:vertical, +QScrollBar::sub-line:vertical { height: 0px; } -QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { +QScrollBar::add-page:vertical, +QScrollBar::sub-page:vertical { background: transparent; } @@ -466,64 +661,129 @@ QTextEdit#mesEdit:focus { } /* ==================== 列表视图样式 ==================== */ -QListView#trendListView { +QListView { + background-color: #FFFFFF; font-size: 14px; font-family: "PingFangSC-Regular", "Microsoft YaHei", sans-serif; border: 1px solid #E5E7EB; border-radius: 6px; - background-color: #FFFFFF; + padding: 4px; } -QListView#trendListView::item { +QListView::item { + border-radius: 4px; padding: 8px 12px; margin: 2px; - border-radius: 4px; + border: none; +} + +QListView::item:hover { + background-color: #F3F4F6; + color: #1F2937; +} + +QListView::item:selected { + background-color: #E3F2FD; + color: #1976D2; + border: none; +} + +/* ==================== 表格视图样式 ==================== */ +QTableView { + background-color: #FFFFFF; + alternate-background-color: #F8F9FA; + gridline-color: #E5E7EB; + selection-background-color: #E3F2FD; + selection-color: #1976D2; + font-size: 13px; + font-family: "PingFangSC-Regular", "Microsoft YaHei", sans-serif; + border: 1px solid #E5E7EB; + border-radius: 6px; +} + +QTableView::item { + padding: 8px 12px; + border: none; + border-bottom: 1px solid #F1F3F4; } -QListView#trendListView::item:hover { +QTableView::item:hover { background-color: #F3F4F6; } -QListView#trendListView::item:selected { +QTableView::item:selected { background-color: #E3F2FD; color: #1976D2; } +/* 表格行交替颜色 */ +QTableView::item:alternate { + background-color: #F8F9FA; +} + +/* 表格焦点样式 */ +QTableView:focus { + border: 2px solid #2277EF; + outline: none; +} + /* ==================== 消息框样式 ==================== */ QMessageBox { background-color: #FFFFFF; - border-radius: 12px; - border: 1px solid #E5E7EB; - min-width: 400px; - min-height: 180px; - font-size: 14px; - padding: 20px; + border-radius: 8px; + font-family: "Microsoft YaHei", "PingFangSC-Regular", sans-serif; + border: 1px solid #d1d9e0; + min-width: 300px; + min-height: 120px; } QMessageBox QLabel { - color: #374151; - font-size: 16px; - font-weight: 600; - padding: 12px 0; + color: #2c3e50; + font-size: 14px; + padding: 10px; + font-weight: 400; } QMessageBox QPushButton { - min-width: 80px; - min-height: 36px; - font-size: 14px; - border-radius: 6px; - background: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #2277EF, - stop:1 #1976D2); + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #2277EF, + stop:1 #1976D2); color: #FFFFFF; - font-weight: 600; - margin: 0 6px; + border: 1px solid #1976D2; + border-radius: 6px; + padding: 8px 16px; + font-weight: bold; + min-width: 80px; + min-height: 32px; + font-size: 13px; + font-family: "PingFangSC-Medium", "Microsoft YaHei", sans-serif; } QMessageBox QPushButton:hover { - background: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #3B82F6, - stop:1 #2277EF); + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #3B82F6, + stop:1 #2277EF); + border-color: #2277EF; +} + +QMessageBox QPushButton:pressed { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #1976D2, + stop:1 #1565C0); + border-color: #1565C0; +} + +QMessageBox QPushButton:default { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #059669, + stop:1 #047857); + border-color: #047857; +} + +QMessageBox QPushButton:default:hover { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #10B981, + stop:1 #059669); } /* ==================== Tab标签页样式 ==================== */ @@ -550,12 +810,7 @@ QTabBar#varManageTabBar::tab:selected { font-weight: 600; } -/* ==================== 趋势界面样式 ==================== */ -QWidget#trendMainWidget { - background-color: #F5F5F5; - border-radius: 8px; -} - +/* ==================== 分组框样式 ==================== */ QGroupBox { font-family: "PingFangSC-Medium", "Microsoft YaHei", sans-serif; font-weight: 600; @@ -583,9 +838,9 @@ QPushButton#registerPushButton { color: #FFFFFF; font-size: 14px; font-weight: 600; - background: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #10B981, - stop:1 #059669); + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #10B981, + stop:1 #059669); } QPushButton#cancel_btn { @@ -605,7 +860,8 @@ QLabel#registerlabel { text-align: center; } -QLabel#registerlabel_1, QLabel#registerlabel_2 { +QLabel#registerlabel_1, +QLabel#registerlabel_2 { color: #FFFFFF; font-size: 15px; font-family: "PingFangSC-Medium", "Microsoft YaHei", sans-serif; @@ -625,694 +881,4 @@ QLineEdit#registerlineEdit { QLineEdit#registerlineEdit:focus { border-color: #2277EF; -} -/* = -=================== 变量表下拉框样式 ==================== */ -/* 基础下拉框样式 */ - - - -/* 移除偶数行样式 - 不需要奇偶行颜色区别 */ - -/* 移除强制变量样式 - 所有下拉框使用统一样式 */ - -/* 下拉箭头样式 - 使用Static/down.png */ - - - - -/* 全局下拉列表样式 - 强制修复黑色背景问题 */ -QComboBox QAbstractItemView { - background-color: white !important; - color: black !important; - border: 1px solid #E5E7EB; - border-radius: 4px; - selection-background-color: #E3F2FD !important; - selection-color: #1976D2 !important; - outline: none; - font-size: 14px; - show-decoration-selected: 1; -} - -QComboBox QAbstractItemView::item { - background-color: white !important; - color: black !important; - padding: 8px 12px; - min-height: 28px; - border: none; -} - -QComboBox QAbstractItemView::item:hover { - background-color: #F3F4F6 !important; - color: black !important; -} - -QComboBox QAbstractItemView::item:selected { - background-color: #E3F2FD !important; - color: #1976D2 !important; -} - - -/* ==================== 历史趋势界面样式 ==================== */ - -/* 主趋势窗口 */ -QWidget#trendMainWidget { - background-color: #F8F9FA; - border: 1px solid #E5E7EB; - border-radius: 8px; -} - -/* 变量列表组 */ -QGroupBox#trendVariableListGroup { - font-size: 14px; - font-weight: bold; - color: #374151; - border: 2px solid #E5E7EB; - border-radius: 8px; - margin-top: 12px; - padding-top: 8px; - background-color: #FFFFFF; -} - -QGroupBox#trendVariableListGroup::title { - subcontrol-origin: margin; - left: 12px; - padding: 0 8px 0 8px; - color: #2277EF; - font-weight: bold; -} - -/* 搜索输入框 */ -QLineEdit#trendSearchInput { - background-color: #FFFFFF; - border: 2px solid #E5E7EB; - border-radius: 6px; - padding: 8px 12px; - font-size: 14px; - color: #374151; -} - -QLineEdit#trendSearchInput:focus { - border-color: #2277EF; - background-color: #F8F9FA; -} - -QLineEdit#trendSearchInput:hover { - border-color: #9CA3AF; -} - -/* 变量列表 */ -QListWidget#trendVarListWidget { - background-color: #FFFFFF; - border: 1px solid #E5E7EB; - border-radius: 6px; - selection-background-color: #E3F2FD; - selection-color: #1976D2; - outline: none; - font-size: 13px; - padding: 4px; -} - -QListWidget#trendVarListWidget::item { - padding: 8px 12px; - border-radius: 4px; - margin: 1px; - color: #374151; -} - -QListWidget#trendVarListWidget::item:hover { - background-color: #F3F4F6; - color: #1F2937; -} - -QListWidget#trendVarListWidget::item:selected { - background-color: #E3F2FD; - color: #1976D2; - font-weight: bold; -} - -/* 时间范围组 */ -QGroupBox#trendTimeGroupBox { - font-size: 13px; - font-weight: bold; - color: #374151; - border: 2px solid #E5E7EB; - border-radius: 6px; - margin-top: 10px; - padding-top: 6px; - background-color: #FFFFFF; -} - -QGroupBox#trendTimeGroupBox::title { - subcontrol-origin: margin; - left: 10px; - padding: 0 6px 0 6px; - color: #059669; - font-weight: bold; -} - -/* 快速时间范围下拉框 */ -QComboBox#trendQuickRangeCombo { - background-color: #FFFFFF; - border: 2px solid #E5E7EB; - border-radius: 6px; - padding: 6px 8px; - font-size: 13px; - min-height: 24px; - color: #374151; -} - -QComboBox#trendQuickRangeCombo:hover { - border-color: #059669; - background-color: #F0FDF4; -} - -QComboBox#trendQuickRangeCombo::drop-down { - subcontrol-origin: padding; - subcontrol-position: top right; - width: 20px; - border-left-width: 1px; - border-left-color: #E5E7EB; - border-left-style: solid; - border-top-right-radius: 6px; - border-bottom-right-radius: 6px; - background-color: #F8F9FA; -} - -QComboBox#trendQuickRangeCombo::down-arrow { - image: url(Static/down.png); - width: 12px; - height: 8px; -} - -QComboBox#trendQuickRangeCombo QAbstractItemView { - background-color: #FFFFFF; - color: #374151; - border: 1px solid #E5E7EB; - border-radius: 4px; - selection-background-color: #F0FDF4; - selection-color: #059669; - outline: none; - font-size: 13px; -} - -/* 时间编辑器 */ -QDateTimeEdit#trendStartTimeEdit, QDateTimeEdit#trendEndTimeEdit { - background-color: #FFFFFF; - border: 2px solid #E5E7EB; - border-radius: 6px; - padding: 6px 8px; - font-size: 13px; - color: #374151; - min-height: 24px; -} - -QDateTimeEdit#trendStartTimeEdit:focus, QDateTimeEdit#trendEndTimeEdit:focus { - border-color: #059669; - background-color: #F0FDF4; -} - -QDateTimeEdit#trendStartTimeEdit:hover, QDateTimeEdit#trendEndTimeEdit:hover { - border-color: #9CA3AF; -} - -/* 操作按钮组 */ -QGroupBox#trendButtonGroupBox { - font-size: 13px; - font-weight: bold; - color: #374151; - border: 2px solid #E5E7EB; - border-radius: 6px; - margin-top: 10px; - padding-top: 6px; - background-color: #FFFFFF; -} - -QGroupBox#trendButtonGroupBox::title { - subcontrol-origin: margin; - left: 10px; - padding: 0 6px 0 6px; - color: #059669; - font-weight: bold; -} - -/* 趋势操作按钮 */ -QToolButton#trendQueryBtn { - background-color: #2277EF; - color: #FFFFFF; - border: none; - border-radius: 6px; - padding: 12px 16px; - font-size: 13px; - font-weight: bold; - min-height: 40px; - min-width: 120px; -} - -QToolButton#trendQueryBtn:hover { - background-color: #1D4ED8; - border: 2px solid #1E40AF; -} - -QToolButton#trendQueryBtn:pressed { - background-color: #1E40AF; - border: 2px solid #1D4ED8; -} - -QToolButton#trendRefreshBtn { - background-color: #059669; - color: #FFFFFF; - border: none; - border-radius: 6px; - padding: 12px 16px; - font-size: 13px; - font-weight: bold; - min-height: 40px; - min-width: 120px; -} - -QToolButton#trendRefreshBtn:hover { - background-color: #047857; - border: 2px solid #065F46; -} - -QToolButton#trendRefreshBtn:pressed { - background-color: #065F46; - border: 2px solid #047857; -} - -QToolButton#trendAddBtn { - background-color: #7C3AED; - color: #FFFFFF; - border: none; - border-radius: 6px; - padding: 12px 16px; - font-size: 13px; - font-weight: bold; - min-height: 40px; - min-width: 120px; -} - -QToolButton#trendAddBtn:hover { - background-color: #6D28D9; - border: 2px solid #5B21B6; -} - -QToolButton#trendAddBtn:pressed { - background-color: #5B21B6; - border: 2px solid #6D28D9; -} - -QToolButton#trendClearBtn { - background-color: #DC2626; - color: #FFFFFF; - border: none; - border-radius: 6px; - padding: 12px 16px; - font-size: 13px; - font-weight: bold; - min-height: 40px; - min-width: 120px; -} - -QToolButton#trendClearBtn:hover { - background-color: #B91C1C; - border: 2px solid #991B1B; -} - -QToolButton#trendClearBtn:pressed { - background-color: #991B1B; - border: 2px solid #B91C1C; -} - -/* 趋势图查看器组 */ -QWidget#trendViewerGroup { - background-color: #FFFFFF; - border: 1px solid #E5E7EB; - border-radius: 8px; -} - -/* 图表组 */ -QGroupBox#trendChartGroup { - font-size: 16px; - font-weight: bold; - color: #1F2937; - border: 2px solid #E5E7EB; - border-radius: 8px; - margin-top: 12px; - padding-top: 8px; - background-color: #FFFFFF; -} - -QGroupBox#trendChartGroup::title { - subcontrol-origin: margin; - left: 12px; - padding: 0 8px 0 8px; - color: #2277EF; - font-weight: bold; -} - -/* 信息状态组 */ -QGroupBox#trendInfoGroup { - font-size: 13px; - font-weight: bold; - color: #374151; - border: 2px solid #E5E7EB; - border-radius: 6px; - margin-top: 8px; - padding-top: 6px; - background-color: #F8F9FA; -} - -QGroupBox#trendInfoGroup::title { - subcontrol-origin: margin; - left: 10px; - padding: 0 6px 0 6px; - color: #6B7280; - font-weight: bold; -} - -/* 状态标签 */ -QLabel#trendVarNameLabel { - color: #1F2937; - font-size: 13px; - font-weight: bold; - padding: 4px 8px; - background-color: #E3F2FD; - border-radius: 4px; -} - -QLabel#trendDataCountLabel { - color: #059669; - font-size: 13px; - font-weight: bold; - padding: 4px 8px; - background-color: #D1FAE5; - border-radius: 4px; -} - -QLabel#trendTimeRangeLabel { - color: #7C3AED; - font-size: 13px; - font-weight: bold; - padding: 4px 8px; - background-color: #F3E8FF; - border-radius: 4px; -} - -QLabel#trendStatusLabel { - color: #DC2626; - font-size: 13px; - font-weight: bold; - padding: 4px 8px; - background-color: #FEF2F2; - border-radius: 4px; -} - -/* 信息气泡 */ -QLabel#trendInfoBubble { - background-color: rgba(0, 0, 0, 200); - color: #FFFFFF; - border: none; - border-radius: 6px; - padding: 8px 12px; - font-size: 12px; - font-weight: bold; -} - -/* ==================== 实时趋势界面样式 ==================== */ - -/* 实时趋势主窗口 */ -ActualTrend { - background-color: #F8F9FA; - border: 1px solid #E5E7EB; - border-radius: 8px; -} - -/* 实时趋势工具栏 */ -ActualTrend QToolBar { - background-color: #FFFFFF; - border: 1px solid #E5E7EB; - border-radius: 6px; - spacing: 4px; - padding: 4px; -} - -ActualTrend QToolBar::handle { - background-color: #9CA3AF; - width: 8px; - border-radius: 4px; - margin: 4px; -} - -ActualTrend QToolBar::separator { - background-color: #E5E7EB; - width: 1px; - margin: 4px; -} - -/* 实时趋势画布容器 */ -ActualTrend QWidget { - background-color: #FFFFFF; - border-radius: 6px; -} - -/* ==================== 趋势界面通用样式 ==================== */ - -/* 所有趋势相关的滚动条 */ -QWidget[objectName*="trend"] QScrollBar:vertical { - background-color: #F3F4F6; - width: 12px; - border-radius: 6px; - margin: 0; -} - -QWidget[objectName*="trend"] QScrollBar::handle:vertical { - background-color: #9CA3AF; - border-radius: 6px; - min-height: 20px; - margin: 2px; -} - -QWidget[objectName*="trend"] QScrollBar::handle:vertical:hover { - background-color: #6B7280; -} - -QWidget[objectName*="trend"] QScrollBar::add-line:vertical, -QWidget[objectName*="trend"] QScrollBar::sub-line:vertical { - height: 0px; -} - -/* 趋势界面的分割器 */ -QWidget[objectName*="trend"] QSplitter::handle { - background-color: #E5E7EB; - border-radius: 2px; -} - -QWidget[objectName*="trend"] QSplitter::handle:hover { - background-color: #9CA3AF; -} - -/* 趋势界面的复选框 */ -QWidget[objectName*="trend"] QCheckBox { - color: #374151; - font-size: 13px; - spacing: 8px; -} - -QWidget[objectName*="trend"] QCheckBox::indicator { - width: 16px; - height: 16px; - border-radius: 3px; - border: 2px solid #9CA3AF; - background-color: #FFFFFF; -} - -QWidget[objectName*="trend"] QCheckBox::indicator:hover { - border-color: #2277EF; -} - -QWidget[objectName*="trend"] QCheckBox::indicator:checked { - background-color: #2277EF; - border-color: #2277EF; - image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iOSIgdmlld0JveD0iMCAwIDEyIDkiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Ik0xIDQuNUw0LjUgOEwxMSAxIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8L3N2Zz4K); -} - -/* 趋势界面的标签通用样式 */ -QWidget[objectName*="trend"] QLabel { - color: #374151; - font-size: 13px; -} - -/* 趋势界面的输入框通用样式 */ -QWidget[objectName*="trend"] QLineEdit { - background-color: #FFFFFF; - border: 1px solid #D1D5DB; - border-radius: 4px; - padding: 6px 8px; - font-size: 13px; - color: #374151; -} - -QWidget[objectName*="trend"] QLineEdit:focus { - border-color: #2277EF; - outline: none; -} - -/* 趋势界面的按钮通用悬停效果 */ -QWidget[objectName*="trend"] QPushButton:hover, -QWidget[objectName*="trend"] QToolButton:hover { - border: 2px solid #9CA3AF; -} - -QWidget[objectName*="trend"] QPushButton:pressed, -QWidget[objectName*="trend"] QToolButton:pressed { - border: 2px solid #6B7280; -} - -/* ==================== 表格整行Hover样式 ==================== */ - -/* 通用表格样式 - 整行hover效果 */ -QTableView { - selection-background-color: #E3F2FD; - selection-color: #1976D2; - gridline-color: #E5E7EB; - background-color: #FFFFFF; - alternate-background-color: #F8F9FA; - outline: none; -} - -/* 表格项整行hover效果 */ -QTableView::item { - padding: 8px; - border: none; - color: #374151; -} - -QTableView::item:hover { - background-color: #F3F4F6; - color: #1F2937; -} - -QTableView::item:selected { - background-color: #E3F2FD; - color: #1976D2; -} - -QTableView::item:selected:hover { - background-color: #BBDEFB; - color: #1565C0; -} - -/* 变量表格特定样式 */ -QTableView#varView { - selection-background-color: #E3F2FD; - selection-color: #1976D2; - gridline-color: #E5E7EB; - background-color: #FFFFFF; - outline: none; - show-decoration-selected: 1; -} - -QTableView#varView::item { - padding: 6px 8px; - border: none; - color: #374151; -} - -QTableView#varView::item:hover { - background-color: #F0F9FF; - color: #1F2937; -} - -QTableView#varView::item:selected { - background-color: #E3F2FD; - color: #1976D2; -} - -QTableView#varView::item:selected:hover { - background-color: #BBDEFB; - color: #1565C0; -} - -/* 项目表格样式 */ -QTableView#projectTable { - selection-background-color: #F0FDF4; - selection-color: #059669; - gridline-color: #E5E7EB; - background-color: #FFFFFF; - outline: none; - show-decoration-selected: 1; -} - -QTableView#projectTable::item { - padding: 8px; - border: none; - color: #374151; -} - -QTableView#projectTable::item:hover { - background-color: #F0FDF4; - color: #1F2937; -} - -QTableView#projectTable::item:selected { - background-color: #D1FAE5; - color: #059669; -} - -QTableView#projectTable::item:selected:hover { - background-color: #A7F3D0; - color: #047857; -} - -/* 用户表格样式 */ -QTableView#userTable { - selection-background-color: #FEF3C7; - selection-color: #D97706; - gridline-color: #E5E7EB; - background-color: #FFFFFF; - outline: none; - show-decoration-selected: 1; -} - -QTableView#userTable::item { - padding: 8px; - border: none; - color: #374151; -} - -QTableView#userTable::item:hover { - background-color: #FFFBEB; - color: #1F2937; -} - -QTableView#userTable::item:selected { - background-color: #FEF3C7; - color: #D97706; -} - -QTableView#userTable::item:selected:hover { - background-color: #FDE68A; - color: #B45309; -} - -/* 趋势变量列表样式 */ -QListWidget#trendVarListWidget::item:hover { - background-color: #F0F9FF; - color: #1F2937; - border-radius: 4px; -} - -QListWidget#trendVarListWidget::item:selected { - background-color: #E3F2FD; - color: #1976D2; - border-radius: 4px; -} - -QListWidget#trendVarListWidget::item:selected:hover { - background-color: #BBDEFB; - color: #1565C0; - border-radius: 4px; -} - +} \ No newline at end of file diff --git a/Static/Procedure.qss b/Static/Procedure.qss index da72041..ede668f 100644 --- a/Static/Procedure.qss +++ b/Static/Procedure.qss @@ -1,388 +1,373 @@ -/* 规程管理系统 - 白色浅蓝色QSS样式 */ +/* ==================== DCS2025 规程管理界面样式 - 现代化设计 ==================== */ /* ==================== 全局样式 ==================== */ QWidget { - background-color: #ffffff; - color: #2c3e50; - font-family: "Microsoft YaHei", "Segoe UI", Arial, sans-serif; - font-size: 9pt; - selection-background-color: #3498db; - selection-color: #ffffff; + background-color: #F5F7FA; + color: #374151; + font-family: "PingFangSC-Regular", "Microsoft YaHei", "Segoe UI", Arial, sans-serif; + font-size: 14px; + selection-background-color: #3B82F6; + selection-color: #FFFFFF; } -/* ==================== 主窗口 ==================== */ +/* ==================== 主窗口样式 ==================== */ QMainWindow { - background-color: #f8f9fa; + background-color: #F5F7FA; border: none; } -QMainWindow::separator { - background-color: #bdc3c7; - width: 2px; - height: 2px; -} - -/* ==================== 工具栏 ==================== */ +/* ==================== 工具栏样式 ==================== */ QToolBar { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #ecf0f1, stop: 1 #d5dbdb); + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #FFFFFF, stop:1 #F8FAFC); border: none; - spacing: 3px; - padding: 5px; - border-bottom: 2px solid #3498db; + border-bottom: 1px solid #E5E7EB; + spacing: 12px; + padding: 16px 24px; + font-size: 13px; + font-weight: 500; } -QToolBar::handle { - background: #bdc3c7; - width: 8px; - margin: 2px; +QToolBar::separator { + background-color: #E5E7EB; + width: 1px; + margin: 8px 6px; } +/* 工具栏按钮 */ QToolBar QToolButton { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #ffffff, stop: 1 #ecf0f1); - border: 1px solid #bdc3c7; - border-radius: 6px; - padding: 8px 12px; - margin: 2px; - color: #2c3e50; - font-weight: bold; + background-color: #FFFFFF; + border: 1px solid #E5E7EB; + border-radius: 8px; + padding: 12px 16px; + margin: 4px 2px; + color: #374151; + font-size: 13px; + font-weight: 500; + min-width: 80px; + min-height: 36px; } QToolBar QToolButton:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #e8f4fd, stop: 1 #d6eaff); - border: 1px solid #3498db; + background-color: #F9FAFB; + border-color: #D1D5DB; + color: #1F2937; } QToolBar QToolButton:pressed { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #d6eaff, stop: 1 #c3e2ff); - border: 1px solid #2980b9; -} - -QToolBar QToolButton:disabled { - background: #f5f6fa; - color: #95a5a6; - border: 1px solid #d5dbdb; -} - -/* ==================== 状态栏 ==================== */ -QStatusBar { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #ecf0f1, stop: 1 #d5dbdb); - border-top: 1px solid #bdc3c7; - color: #34495e; - padding: 3px; -} - -QStatusBar::item { - border: none; -} - -/* ==================== 按钮 ==================== */ -QPushButton { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #ffffff, stop: 1 #ecf0f1); - border: 1px solid #bdc3c7; - border-radius: 8px; - padding: 10px 16px; - font-weight: bold; - color: #2c3e50; - min-width: 80px; - min-height: 30px; + background-color: #F3F4F6; + border-color: #9CA3AF; + color: #111827; } -QPushButton:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #e8f4fd, stop: 1 #d6eaff); - border: 1px solid #3498db; -} - -QPushButton:pressed { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #d6eaff, stop: 1 #c3e2ff); - border: 1px solid #2980b9; +/* ==================== 标签页样式 ==================== */ +QTabWidget::pane { + border: 1px solid #E5E7EB; + border-radius: 12px; + background-color: #FFFFFF; + margin-top: -1px; } -QPushButton:disabled { - background: #f5f6fa; - color: #95a5a6; - border: 1px solid #d5dbdb; +QTabWidget::tab-bar { + alignment: left; } -/* 特殊按钮颜色 */ -QPushButton[text*="开始"], QPushButton[text*="执行"] { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #58d68d, stop: 1 #27ae60); - border: 1px solid #2ecc71; - color: #ffffff; +QTabBar::tab { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #F9FAFB, stop:1 #F3F4F6); + border: 1px solid #E5E7EB; + border-bottom: none; + border-top-left-radius: 12px; + border-top-right-radius: 12px; + padding: 16px 24px; + margin-right: 4px; + color: #6B7280; + font-size: 14px; + font-weight: 500; + min-width: 140px; } -QPushButton[text*="开始"]:hover, QPushButton[text*="执行"]:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #7dcea0, stop: 1 #58d68d); +QTabBar::tab:selected { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #FFFFFF, stop:1 #F8FAFC); + color: #1976D2; + border-color: #E5E7EB; + font-weight: 600; } -QPushButton[text*="停止"], QPushButton[text*="删除"] { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #ec7063, stop: 1 #e74c3c); - border: 1px solid #e67e22; - color: #ffffff; +QTabBar::tab:hover:!selected { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #FFFFFF, stop:1 #F9FAFB); + color: #374151; } -QPushButton[text*="停止"]:hover, QPushButton[text*="删除"]:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #f1948a, stop: 1 #ec7063); +/* 关闭按钮 */ +QTabBar::close-button { + image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEyIDRMNCA4TDEyIDEyIiBzdHJva2U9IiM2QjcyODAiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjwvc3ZnPgo=); + subcontrol-position: right; + subcontrol-origin: padding; + border-radius: 4px; + margin: 6px; + padding: 2px; } -QPushButton[text*="重置"] { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #f7dc6f, stop: 1 #f39c12); - border: 1px solid #f1c40f; - color: #ffffff; +QTabBar::close-button:hover { + background-color: #FEE2E2; + border: 1px solid #FECACA; } -QPushButton[text*="重置"]:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #f8e6a0, stop: 1 #f7dc6f); +/* ==================== 卡片式容器样式 ==================== */ +/* 分类列表卡片 */ +QWidget#categoryCard { + background-color: #FFFFFF; + border: 1px solid #E5E7EB; + border-radius: 12px; + padding: 20px; + margin: 8px; } -QPushButton[text*="报告"], QPushButton[text*="导入"] { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #bb8fce, stop: 1 #9b59b6); - border: 1px solid #af7ac5; - color: #ffffff; +/* 规程列表卡片 */ +QWidget#procedureCard { + background-color: #FFFFFF; + border: 1px solid #E5E7EB; + border-radius: 12px; + padding: 20px; + margin: 8px; } -QPushButton[text*="报告"]:hover, QPushButton[text*="导入"]:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #d2b4de, stop: 1 #bb8fce); +/* 卡片标题 */ +QLabel#cardTitle { + font-size: 16px; + font-weight: 600; + color: #1F2937; + padding: 0 0 12px 0; + border-bottom: 2px solid #E5E7EB; + margin-bottom: 16px; +} + +/* ==================== 列表控件样式 ==================== */ +/* 分类列表 */ +QListWidget#categoryList { + background-color: #FFFFFF; + border: 1px solid #E5E7EB; + border-radius: 8px; + padding: 8px; + outline: none; + font-size: 14px; } -/* ==================== 规程界面按钮样式 ==================== */ -/* 开始自动执行按钮 - 绿色主题 */ -QPushButton[text*="开始自动执行"] { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #28a745, stop: 1 #218838); - border: 2px solid #28a745; +QListWidget#categoryList::item { + background-color: transparent; + border: none; border-radius: 6px; - color: #ffffff; - font-size: 13px; - font-weight: bold; - min-width: 140px; - padding: 10px 20px; - icon-size: 16px 16px; + padding: 12px 16px; + margin: 2px 0; + color: #374151; + font-weight: 500; } -QPushButton[text*="开始自动执行"]:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #218838, stop: 1 #1e7e34); - border-color: #1e7e34; +QListWidget#categoryList::item:hover { + background-color: #F3F4F6; + color: #1F2937; } -QPushButton[text*="开始自动执行"]:pressed { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #1e7e34, stop: 1 #1c7430); - border-color: #1c7430; +QListWidget#categoryList::item:selected { + background: qlineargradient(x1:0, y1:0, x2:1, y2:0, + stop:0 #3B82F6, stop:1 #2563EB); + color: #FFFFFF; + font-weight: 600; } -QPushButton[text*="开始自动执行"]:disabled { - background: #6c757d; - border-color: #6c757d; - color: #adb5bd; +/* 规程列表 */ +QListWidget#procedureList { + background-color: #FFFFFF; + border: 1px solid #E5E7EB; + border-radius: 8px; + padding: 8px; + outline: none; + font-size: 14px; } -/* 停止自动执行按钮 - 红色主题 */ -QPushButton[text*="停止自动执行"] { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #dc3545, stop: 1 #c82333); - border: 2px solid #dc3545; +QListWidget#procedureList::item { + background-color: transparent; + border: none; border-radius: 6px; - color: #ffffff; - font-size: 13px; - font-weight: bold; - min-width: 140px; - padding: 10px 20px; - icon-size: 16px 16px; + padding: 16px 20px; + margin: 3px 0; + color: #374151; + font-weight: 500; + min-height: 20px; } -QPushButton[text*="停止自动执行"]:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #c82333, stop: 1 #bd2130); - border-color: #bd2130; +QListWidget#procedureList::item:hover { + background-color: #F8FAFC; + border: 1px solid #E5E7EB; + color: #1F2937; } -QPushButton[text*="停止自动执行"]:pressed { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #bd2130, stop: 1 #b21f2d); - border-color: #b21f2d; +QListWidget#procedureList::item:selected { + background: qlineargradient(x1:0, y1:0, x2:1, y2:0, + stop:0 #EBF8FF, stop:1 #DBEAFE); + border: 1px solid #93C5FD; + color: #1E40AF; + font-weight: 600; } -QPushButton[text*="停止自动执行"]:disabled { - background: #6c757d; - border-color: #6c757d; - color: #adb5bd; +/* ==================== 按钮样式 ==================== */ +/* 基础按钮样式 */ +QPushButton { + background-color: #FFFFFF; + border: 1px solid #E5E7EB; + border-radius: 8px; + padding: 12px 20px; + font-weight: 500; + color: #374151; + font-size: 14px; + min-width: 100px; + min-height: 36px; } -/* 执行下一步按钮 - 蓝色主题 */ -QPushButton[text*="执行下一步"] { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #007bff, stop: 1 #0056b3); - border: 2px solid #007bff; - border-radius: 6px; - color: #ffffff; - font-size: 13px; - font-weight: bold; - min-width: 140px; - padding: 10px 20px; - icon-size: 16px 16px; +QPushButton:hover { + background-color: #F9FAFB; + border-color: #D1D5DB; + color: #1F2937; } -QPushButton[text*="执行下一步"]:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #0056b3, stop: 1 #004085); - border-color: #004085; +QPushButton:pressed { + background-color: #F3F4F6; + border-color: #9CA3AF; + color: #111827; } -QPushButton[text*="执行下一步"]:pressed { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #004085, stop: 1 #003d7a); - border-color: #003d7a; +QPushButton:disabled { + background-color: #F9FAFB; + color: #9CA3AF; + border-color: #E5E7EB; } -QPushButton[text*="执行下一步"]:disabled { - background: #6c757d; - border-color: #6c757d; - color: #adb5bd; +/* 主要操作按钮 - 蓝色 */ +QPushButton#primaryBtn { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #3B82F6, stop:1 #2563EB); + border: 1px solid #2563EB; + color: #FFFFFF; + font-weight: 600; } -/* 完全重置按钮 - 橙色主题 */ -QPushButton[text*="完全重置"] { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #fd7e14, stop: 1 #e8690b); - border: 2px solid #fd7e14; - border-radius: 6px; - color: #ffffff; - font-size: 13px; - font-weight: bold; - min-width: 140px; - padding: 10px 20px; - icon-size: 16px 16px; +QPushButton#primaryBtn:hover { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #2563EB, stop:1 #1D4ED8); + border-color: #1D4ED8; } -QPushButton[text*="完全重置"]:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #e8690b, stop: 1 #d6620a); - border-color: #d6620a; +QPushButton#primaryBtn:pressed { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #1D4ED8, stop:1 #1E40AF); + border-color: #1E40AF; } -QPushButton[text*="完全重置"]:pressed { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #d6620a, stop: 1 #c55a09); - border-color: #c55a09; +/* 成功操作按钮 - 绿色 */ +QPushButton#successBtn { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #10B981, stop:1 #059669); + border: 1px solid #059669; + color: #FFFFFF; + font-weight: 600; } -QPushButton[text*="完全重置"]:disabled { - background: #6c757d; - border-color: #6c757d; - color: #adb5bd; +QPushButton#successBtn:hover { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #059669, stop:1 #047857); + border-color: #047857; } -/* 生成报告按钮 - 紫色主题 */ -QPushButton[text*="生成报告"] { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #6f42c1, stop: 1 #5a32a3); - border: 2px solid #6f42c1; - border-radius: 6px; - color: #ffffff; - font-size: 13px; - font-weight: bold; - min-width: 140px; - padding: 10px 20px; - icon-size: 16px 16px; +QPushButton#successBtn:pressed { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #047857, stop:1 #065F46); + border-color: #065F46; } -QPushButton[text*="生成报告"]:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #5a32a3, stop: 1 #4c2a85); - border-color: #4c2a85; +/* 警告操作按钮 - 橙色 */ +QPushButton#warningBtn { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #F59E0B, stop:1 #D97706); + border: 1px solid #D97706; + color: #FFFFFF; + font-weight: 600; } -QPushButton[text*="生成报告"]:pressed { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #4c2a85, stop: 1 #3d2175); - border-color: #3d2175; +QPushButton#warningBtn:hover { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #D97706, stop:1 #B45309); + border-color: #B45309; } -QPushButton[text*="生成报告"]:disabled { - background: #6c757d; - border-color: #6c757d; - color: #adb5bd; +QPushButton#warningBtn:pressed { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #B45309, stop:1 #92400E); + border-color: #92400E; } -/* ==================== 标签 ==================== */ -QLabel { - color: #2c3e50; - background: transparent; - font-weight: normal; +/* 危险操作按钮 - 红色 */ +QPushButton#dangerBtn { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #EF4444, stop:1 #DC2626); + border: 1px solid #DC2626; + color: #FFFFFF; + font-weight: 600; } -QLabel[text="规程分类"], QLabel[text="规程列表"], QLabel[text="测试步骤:"] { - font-size: 11pt; - font-weight: bold; - color: #3498db; - padding: 5px 0px; +QPushButton#dangerBtn:hover { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #DC2626, stop:1 #B91C1C); + border-color: #B91C1C; } -/* ==================== 表格视图 ==================== */ -QTableView { - background-color: #ffffff; - alternate-background-color: #f8f9fa; - gridline-color: #d5dbdb; - border: 1px solid #bdc3c7; - border-radius: 8px; - selection-background-color: #3498db; - selection-color: #ffffff; +QPushButton#dangerBtn:pressed { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #B91C1C, stop:1 #991B1B); + border-color: #991B1B; } +/* ==================== 表格样式 ==================== */ QTableWidget { - background-color: #ffffff; - alternate-background-color: #f8f9fa; - gridline-color: #d5dbdb; - border: 1px solid #bdc3c7; + background-color: #FFFFFF; + alternate-background-color: #F8FAFC; + gridline-color: #E5E7EB; + border: 1px solid #E5E7EB; border-radius: 8px; - selection-background-color: #3498db; - selection-color: #ffffff; + selection-background-color: #EBF8FF; + selection-color: #1E40AF; outline: none; + font-size: 13px; } QTableWidget::item { - padding: 8px; + padding: 12px 16px; border: none; background-color: transparent; } QTableWidget::item:selected { - background-color: #3498db; - color: #ffffff; + background-color: #EBF8FF; + color: #1E40AF; } QTableWidget::item:hover { - background-color: #e8f4fd; + background-color: #F8FAFC; } +/* 表头样式 */ QHeaderView::section { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #ffffff, stop: 1 #ecf0f1); - color: #2c3e50; - padding: 12px 8px; + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #F9FAFB, stop:1 #F3F4F6); + color: #374151; + padding: 16px 12px; border: none; - border-right: 1px solid #bdc3c7; - border-bottom: 2px solid #3498db; - font-weight: bold; - font-size: 10pt; - min-height: 45px; + border-right: 1px solid #E5E7EB; + border-bottom: 2px solid #E5E7EB; + font-weight: 600; + font-size: 13px; text-align: center; } @@ -396,719 +381,841 @@ QHeaderView::section:last { } QHeaderView::section:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #e8f4fd, stop: 1 #d6eaff); + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #F3F4F6, stop:1 #E5E7EB); } -/* 规程编辑器表格特殊样式 */ -QTableWidget#stepsTable { - background-color: #ffffff; - border: 2px solid #bdc3c7; +/* ==================== 输入控件样式 ==================== */ +QLineEdit { + background-color: #FFFFFF; + border: 2px solid #E5E7EB; border-radius: 8px; - gridline-color: #d5dbdb; + padding: 12px 16px; + color: #374151; + font-size: 14px; + font-weight: 400; } -QTableWidget#stepsTable::item { - padding: 10px 8px; - border: none; - background-color: transparent; - font-size: 9pt; +QLineEdit:focus { + border-color: #3B82F6; + background-color: #FEFEFF; + outline: none; } -QTableWidget#stepsTable::item:selected { - background-color: #3498db; - color: #ffffff; +QLineEdit:hover { + border-color: #9CA3AF; } -QTableWidget#stepsTable::item:hover { - background-color: #e8f4fd; +QTextEdit { + background-color: #FFFFFF; + border: 2px solid #E5E7EB; + border-radius: 8px; + padding: 16px; + color: #374151; + font-size: 14px; + line-height: 1.5; } -/* 主步骤样式 */ -QTableWidget#stepsTable::item[main_step="true"] { - background-color: #dcdcdc; - font-weight: bold; - color: #2c3e50; +QTextEdit:focus { + border-color: #3B82F6; + background-color: #FEFEFF; + outline: none; } -/* 子步骤样式 */ -QTableWidget#stepsTable::item[sub_step="true"] { - background-color: #f8f9fa; - color: #2c3e50; +/* ==================== 组合框样式 ==================== */ +QComboBox { + background-color: #FFFFFF; + border: 2px solid #E5E7EB; + border-radius: 8px; + padding: 12px 16px; + color: #374151; + font-size: 14px; + min-width: 120px; } -/* 表格行高设置 */ -QTableWidget#stepsTable { - gridline-color: #d5dbdb; - alternate-background-color: #f8f9fa; +QComboBox:focus { + border-color: #3B82F6; + background-color: #FEFEFF; } -QTableWidget#stepsTable::item { - min-height: 35px; - padding: 8px 12px; +QComboBox::drop-down { + border: none; + width: 32px; +} + +QComboBox::down-arrow { + image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQgNkw4IDEwTDEyIDYiIHN0cm9rZT0iIzM3NDE1MSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPC9zdmc+); + width: 16px; + height: 16px; } -/* ==================== 列表控件 ==================== */ -QListWidget { - background-color: #ffffff; - border: 1px solid #bdc3c7; +QComboBox QAbstractItemView { + background-color: #FFFFFF; + border: 1px solid #E5E7EB; border-radius: 8px; - padding: 5px; - outline: none; + color: #374151; + selection-background-color: #EBF8FF; + selection-color: #1E40AF; + padding: 4px; } -QListWidget::item { - background-color: transparent; +QComboBox QAbstractItemView::item { + height: 36px; + padding: 8px 16px; border: none; - border-radius: 4px; - padding: 10px 8px; - margin: 2px; - color: #2c3e50; + border-radius: 6px; } -QListWidget::item:hover { - background-color: #e8f4fd; - border: 1px solid #3498db; +QComboBox QAbstractItemView::item:hover { + background-color: #F8FAFC; } -QListWidget::item:selected { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #3498db, stop: 1 #2980b9); - color: #ffffff; - border: 1px solid #5dade2; +QComboBox QAbstractItemView::item:selected { + background-color: #EBF8FF; + color: #1E40AF; } -/* ==================== 选项卡 ==================== */ -QTabWidget::pane { - border: 1px solid #bdc3c7; - border-radius: 8px; - background-color: #ffffff; - top: -1px; +/* ==================== 复选框样式 ==================== */ +QCheckBox { + color: #374151; + spacing: 12px; + font-size: 14px; } -QTabBar::tab { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #ffffff, stop: 1 #ecf0f1); - border: 1px solid #bdc3c7; - padding: 10px 20px; - margin-right: 2px; - border-top-left-radius: 8px; - border-top-right-radius: 8px; - color: #34495e; +QCheckBox::indicator { + width: 20px; + height: 20px; + border: 2px solid #E5E7EB; + border-radius: 4px; + background-color: #FFFFFF; } -QTabBar::tab:selected { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #3498db, stop: 1 #2980b9); - color: #ffffff; - border-bottom-color: #ffffff; +QCheckBox::indicator:hover { + border-color: #3B82F6; + background-color: #F8FAFC; } -QTabBar::tab:hover:!selected { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #e8f4fd, stop: 1 #d6eaff); +QCheckBox::indicator:checked { + background-color: #3B82F6; + border-color: #2563EB; + image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEzIDRMNiAxMUwzIDgiIHN0cm9rZT0iI0ZGRkZGRiIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPC9zdmc+); } -/* ==================== 输入控件 ==================== */ -QLineEdit { - background-color: #ffffff; - border: 2px solid #bdc3c7; - border-radius: 6px; - padding: 8px 12px; - color: #2c3e50; - font-size: 9pt; +QCheckBox::indicator:checked:hover { + background-color: #2563EB; } -QLineEdit:focus { - border: 2px solid #3498db; - background-color: #fdfdfe; +/* ==================== 进度条样式 ==================== */ +QProgressBar { + background-color: #F3F4F6; + border: 1px solid #E5E7EB; + border-radius: 8px; + text-align: center; + color: #374151; + font-weight: 600; + font-size: 13px; + height: 24px; } -QLineEdit:hover { - border: 2px solid #3498db; +QProgressBar::chunk { + background: qlineargradient(x1:0, y1:0, x2:1, y2:0, + stop:0 #3B82F6, stop:1 #2563EB); + border-radius: 7px; + margin: 1px; } -QSpinBox { - background-color: #ffffff; - border: 2px solid #bdc3c7; +/* ==================== 滚动条样式 ==================== */ +QScrollBar:vertical { + background-color: #F9FAFB; + width: 12px; border-radius: 6px; - padding: 8px; - color: #2c3e50; - min-width: 60px; + margin: 0px; } -QSpinBox:focus { - border: 2px solid #3498db; - background-color: #fdfdfe; +QScrollBar::handle:vertical { + background: qlineargradient(x1:0, y1:0, x2:1, y2:0, + stop:0 #E5E7EB, stop:1 #D1D5DB); + border-radius: 6px; + min-height: 30px; } -QSpinBox::up-button, QSpinBox::down-button { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #ffffff, stop: 1 #ecf0f1); - border: 1px solid #bdc3c7; - width: 20px; +QScrollBar::handle:vertical:hover { + background: qlineargradient(x1:0, y1:0, x2:1, y2:0, + stop:0 #3B82F6, stop:1 #2563EB); } -QSpinBox::up-button:hover, QSpinBox::down-button:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #e8f4fd, stop: 1 #d6eaff); +QScrollBar::handle:vertical:pressed { + background: qlineargradient(x1:0, y1:0, x2:1, y2:0, + stop:0 #2563EB, stop:1 #1D4ED8); } -QSpinBox::up-arrow { - image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAGCAYAAAD37n+BAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABHSURBVBiVY/z//z8DJYCJgUIwqmFUw6gGcjWQ5QdqaKBYA7ma/lOggWwN5PqBGhoo1kCuJnI1/KdAA9ka/lOggVwN5PoBAJZzBTcQ48y8AAAAAElFTkSuQmCC); - width: 8px; - height: 4px; +QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical { + height: 0px; + background: none; } -QSpinBox::down-arrow { - image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAGCAYAAAD37n+BAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXblLm9yZ5vuPBoAAABHSURBVBiVY2D4/58BFWBioBCMahgYDf8p0EC2hv8UaCBbA7ma/lOggWwN5Gqipwayff+fAg1ka/hPgQayNZCriboGAJd7BTc3gZfyAAAAAElFTkSuQmCC); - width: 8px; - height: 4px; +QScrollBar:horizontal { + background-color: #F9FAFB; + height: 12px; + border-radius: 6px; + margin: 0px; } -/* ==================== 复选框 ==================== */ -QCheckBox { - color: #2c3e50; - spacing: 8px; +QScrollBar::handle:horizontal { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #E5E7EB, stop:1 #D1D5DB); + border-radius: 6px; + min-width: 30px; } -QCheckBox::indicator { - width: 18px; - height: 18px; - border: 2px solid #bdc3c7; - border-radius: 3px; - background-color: #ffffff; +QScrollBar::handle:horizontal:hover { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #3B82F6, stop:1 #2563EB); } -QCheckBox::indicator:hover { - border: 2px solid #3498db; - background-color: #e8f4fd; +QScrollBar::handle:horizontal:pressed { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #2563EB, stop:1 #1D4ED8); } -QCheckBox::indicator:checked { - background-color: #3498db; - border: 2px solid #2980b9; - image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAJCAYAAAAGuM1UAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXblLm9yZ5vuPBoAAABmSURBVBiVjZExDsIwEAT3JFpKSoo8gCfwCF7ACyipa3oCb+ANvIEn8AaegJYqLWnSRMmy1/YkFhftzNw9jUajUQMwBTaStpJOkmZm9jSzB/A0sy2wljS193O6nZmdgR/wBhYRcfsDGEwlvgBP2TAAAAAASUVORK5CYII=); +QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal { + width: 0px; + background: none; } -QCheckBox::indicator:checked:hover { - background-color: #5dade2; +/* ==================== 菜单样式 ==================== */ +QMenu { + background-color: #FFFFFF; + border: 1px solid #E5E7EB; + border-radius: 8px; + padding: 8px; + color: #374151; } -/* ==================== 组合框 ==================== */ -QComboBox { - background-color: #ffffff; - border: 2px solid #bdc3c7; +QMenu::item { + background-color: transparent; + padding: 12px 16px; border-radius: 6px; - padding: 8px 12px; - color: #2c3e50; - min-width: 100px; + margin: 2px; + font-size: 14px; } -QComboBox:focus { - border: 2px solid #3498db; - background-color: #fdfdfe; +QMenu::item:selected { + background-color: #EBF8FF; + color: #1E40AF; } -QComboBox::drop-down { - border: none; - width: 30px; +QMenu::item:disabled { + color: #9CA3AF; } -QComboBox::down-arrow { - image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAGCAYAAAD37n+BAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXblLm9yZ5vuPBoAAABHSURBVBiVY2D4/58BFWBioBCMahgYDf8p0EC2hv8UaCBbA7ma/lOggWwN5Gqipwayff+fAg1ka/hPgQayNZCriboGAJd7BTc3gZfyAAAAAElFTkSuQmCC); - width: 12px; - height: 8px; +QMenu::separator { + height: 1px; + background-color: #E5E7EB; + margin: 8px 12px; } -QComboBox QAbstractItemView { - background-color: #ffffff; - border: 1px solid #bdc3c7; - border-radius: 6px; - color: #2c3e50; - selection-background-color: #3498db; - padding: 4px; +/* ==================== 状态栏样式 ==================== */ +QStatusBar { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #F9FAFB, stop:1 #F3F4F6); + border-top: 1px solid #E5E7EB; + color: #6B7280; + padding: 8px 16px; + font-size: 13px; } -QComboBox QAbstractItemView::item { - height: 30px; - padding: 6px 12px; +QStatusBar::item { border: none; - border-radius: 4px; -} - -QComboBox QAbstractItemView::item:hover { - background-color: #e8f4fd; -} - -QComboBox QAbstractItemView::item:selected { - background-color: #3498db; - color: #ffffff; } -/* ==================== 对话框 ==================== */ +/* ==================== 对话框样式 ==================== */ QDialog { - background-color: #ffffff; - border: 1px solid #bdc3c7; + background-color: #FFFFFF; + border: 1px solid #E5E7EB; border-radius: 12px; } QDialogButtonBox QPushButton { min-width: 100px; - padding: 10px 20px; + padding: 12px 24px; } -/* ==================== 消息框 ==================== */ +/* ==================== 消息框样式 ==================== */ QMessageBox { - background-color: #ffffff; - color: #2c3e50; - border-radius: 8px; + background-color: #FFFFFF; + color: #374151; + border-radius: 12px; } QMessageBox QLabel { - color: #2c3e50; - font-size: 10pt; + color: #374151; + font-size: 14px; } QMessageBox QPushButton { min-width: 80px; - padding: 8px 16px; + padding: 10px 20px; } -/* ==================== 表单布局 ==================== */ -QFormLayout QLabel { - font-weight: bold; - color: #3498db; - min-width: 100px; +/* ==================== 工具提示样式 ==================== */ +QToolTip { + background-color: #1F2937; + color: #F9FAFB; + border: 1px solid #374151; + border-radius: 6px; + padding: 8px 12px; + font-size: 13px; + opacity: 240; } -/* ==================== 滚动条 ==================== */ -QScrollBar:vertical { - background-color: #f8f9fa; - width: 12px; - border-radius: 6px; - margin: 0px; +/* ==================== 分割器样式 ==================== */ +QSplitter::handle { + background-color: #E5E7EB; } -QScrollBar::handle:vertical { - background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, - stop: 0 #d5dbdb, stop: 1 #bdc3c7); - border-radius: 6px; - min-height: 30px; +QSplitter::handle:horizontal { + width: 2px; + border-radius: 1px; } -QScrollBar::handle:vertical:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, - stop: 0 #3498db, stop: 1 #2980b9); +QSplitter::handle:vertical { + height: 2px; + border-radius: 1px; } -QScrollBar::handle:vertical:pressed { - background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, - stop: 0 #2980b9, stop: 1 #21618c); +QSplitter::handle:hover { + background-color: #3B82F6; } -QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical { - height: 0px; - background: none; +/* ==================== 特殊状态样式 ==================== */ +/* 成功状态 */ +.status-success { + color: #059669; + font-weight: 600; } -QScrollBar:horizontal { - background-color: #f8f9fa; - height: 12px; - border-radius: 6px; - margin: 0px; +/* 错误状态 */ +.status-error { + color: #DC2626; + font-weight: 600; } -QScrollBar::handle:horizontal { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #d5dbdb, stop: 1 #bdc3c7); - border-radius: 6px; - min-width: 30px; +/* 警告状态 */ +.status-warning { + color: #D97706; + font-weight: 600; } -QScrollBar::handle:horizontal:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #3498db, stop: 1 #2980b9); +/* 信息状态 */ +.status-info { + color: #2563EB; + font-weight: 600; } -QScrollBar::handle:horizontal:pressed { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #2980b9, stop: 1 #21618c); +/* ==================== 规程执行界面特殊样式 ==================== */ +/* 规程信息卡片 */ +QWidget#procedureInfoCard { + background-color: #FFFFFF; + border: 1px solid #E5E7EB; + border-radius: 12px; + padding: 24px; + margin: 12px; } -QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal { - width: 0px; - background: none; +/* 信息组标题 */ +QLabel#infoGroupTitle { + font-size: 14px; + font-weight: 600; + color: #6B7280; + margin-bottom: 8px; } -/* ==================== 菜单 ==================== */ -QMenu { - background-color: #ffffff; - border: 1px solid #bdc3c7; +/* 信息组值 */ +QLabel#infoGroupValue { + font-size: 16px; + font-weight: 600; + color: #1F2937; + padding: 12px 16px; + background-color: #F8FAFC; + border: 1px solid #E5E7EB; border-radius: 8px; - padding: 4px; - color: #2c3e50; + min-height: 20px; } -QMenu::item { +/* 步骤表格特殊样式 */ +QTableWidget#stepsTable { + background-color: #FFFFFF; + border: 1px solid #E5E7EB; + border-radius: 8px; + gridline-color: #F3F4F6; +} + +QTableWidget#stepsTable::item { + padding: 16px 12px; + border: none; background-color: transparent; - padding: 8px 16px; - border-radius: 4px; - margin: 1px; + font-size: 13px; } -QMenu::item:selected { - background-color: #3498db; - color: #ffffff; +QTableWidget#stepsTable::item:selected { + background-color: #EBF8FF; + color: #1E40AF; } -QMenu::item:disabled { - color: #95a5a6; +QTableWidget#stepsTable::item:hover { + background-color: #F8FAFC; } -QMenu::separator { - height: 1px; - background-color: #d5dbdb; - margin: 4px 8px; +/* 主步骤样式 */ +QTableWidget#stepsTable::item[main_step="true"] { + background-color: #F0F9FF; + font-weight: 600; + color: #0C4A6E; } -/* ==================== 进度条 ==================== */ -QProgressBar { - background-color: #ffffff; - border: 1px solid #bdc3c7; - border-radius: 8px; - text-align: center; - color: #2c3e50; - font-weight: bold; +/* 子步骤样式 */ +QTableWidget#stepsTable::item[sub_step="true"] { + background-color: #FEFEFE; + color: #374151; } -QProgressBar::chunk { - background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, - stop: 0 #3498db, stop: 1 #2980b9); - border-radius: 7px; - margin: 1px; +/* 执行成功的步骤 */ +QTableWidget#stepsTable::item[success="true"] { + background-color: rgba(16, 185, 129, 0.1); + color: #059669; } -/* ==================== 工具提示 ==================== */ -QToolTip { - background-color: #ffffff; - color: #2c3e50; - border: 1px solid #3498db; - border-radius: 6px; - padding: 8px; - font-size: 9pt; - opacity: 240; +/* 执行失败的步骤 */ +QTableWidget#stepsTable::item[success="false"] { + background-color: rgba(239, 68, 68, 0.1); + color: #DC2626; +} +/* ===== +=============== 规程执行界面特殊样式 ==================== */ +/* 规程信息网格布局 */ +QWidget#procedureInfoGrid { + background-color: #FFFFFF; + border: 1px solid #E5E7EB; + border-radius: 12px; + padding: 24px; + margin: 12px; } -/* ==================== 分割器 ==================== */ -QSplitter::handle { - background-color: #d5dbdb; +/* 信息项容器 */ +QWidget#infoItem { + background-color: #F8FAFC; + border: 1px solid #E5E7EB; + border-radius: 8px; + padding: 16px; + margin: 8px; } -QSplitter::handle:horizontal { - width: 3px; - border-radius: 1px; +/* 信息项标题 */ +QLabel#infoItemTitle { + font-size: 12px; + font-weight: 600; + color: #6B7280; + margin-bottom: 8px; + text-transform: uppercase; + letter-spacing: 0.5px; } -QSplitter::handle:vertical { - height: 3px; - border-radius: 1px; +/* 信息项值 */ +QLabel#infoItemValue { + font-size: 16px; + font-weight: 600; + color: #1F2937; + padding: 8px 0; + word-wrap: break-word; } -QSplitter::handle:hover { - background-color: #3498db; +/* 执行控制面板 */ +QWidget#executionControlPanel { + background-color: #FFFFFF; + border: 1px solid #E5E7EB; + border-radius: 12px; + padding: 20px; + margin: 12px; } -/* ==================== 特殊样式 ==================== */ -/* 成功状态的行 */ -QTableView::item[success="true"] { - background-color: rgba(46, 204, 113, 0.1); - color: #27ae60; +/* 状态指示器 */ +QLabel#executionStatus { + font-size: 14px; + font-weight: 600; + padding: 8px 16px; + border-radius: 20px; + text-align: center; } -/* 失败状态的行 */ -QTableView::item[success="false"] { - background-color: rgba(231, 76, 60, 0.1); - color: #e74c3c; +/* 状态指示器 - 就绪 */ +QLabel#executionStatus[status="ready"] { + background-color: #F3F4F6; + color: #374151; + border: 1px solid #D1D5DB; } -/* 主步骤样式 */ -QTableView::item[main_step="true"] { - background-color: rgba(52, 152, 219, 0.1); - font-weight: bold; +/* 状态指示器 - 运行中 */ +QLabel#executionStatus[status="running"] { + background-color: #ECFDF5; + color: #166534; + border: 1px solid #BBF7D0; } -/* 状态指示器 */ -.status-success { - color: #27ae60; - font-weight: bold; +/* 状态指示器 - 暂停 */ +QLabel#executionStatus[status="paused"] { + background-color: #FEF3C7; + color: #92400E; + border: 1px solid #FCD34D; } -.status-error { - color: #e74c3c; - font-weight: bold; +/* 状态指示器 - 完成 */ +QLabel#executionStatus[status="completed"] { + background-color: #EBF8FF; + color: #1E40AF; + border: 1px solid #BFDBFE; } -.status-warning { - color: #f39c12; - font-weight: bold; +/* 状态指示器 - 错误 */ +QLabel#executionStatus[status="error"] { + background-color: #FEF2F2; + color: #991B1B; + border: 1px solid #FECACA; } -.status-info { - color: #3498db; - font-weight: bold; +/* 进度指示器 */ +QWidget#progressIndicator { + background-color: #F8FAFC; + border: 1px solid #E5E7EB; + border-radius: 8px; + padding: 16px; + margin: 8px 0; } -/* ==================== 动画效果 ==================== */ -QPushButton { +/* 进度标签 */ +QLabel#progressLabel { + font-size: 14px; + font-weight: 500; + color: #374151; + margin-bottom: 8px; } -QToolButton { +/* 自定义进度条 */ +QProgressBar#executionProgress { + background-color: #F3F4F6; + border: 1px solid #E5E7EB; + border-radius: 10px; + text-align: center; + color: #374151; + font-weight: 600; + font-size: 12px; + height: 20px; } -QLineEdit { +QProgressBar#executionProgress::chunk { + background: qlineargradient(x1:0, y1:0, x2:1, y2:0, + stop:0 #10B981, stop:1 #059669); + border-radius: 9px; + margin: 1px; } -QListWidget::item { +/* 时间显示 */ +QLabel#timeDisplay { + font-size: 18px; + font-weight: 700; + color: #1F2937; + font-family: "Consolas", "Monaco", monospace; + background-color: #F8FAFC; + border: 1px solid #E5E7EB; + border-radius: 8px; + padding: 12px 16px; + text-align: center; } -QTableView::item { +/* 时间显示 - 警告状态 */ +QLabel#timeDisplay[warning="true"] { + color: #D97706; + background-color: #FEF3C7; + border-color: #FCD34D; } -/* ==================== 规程编辑器样式 ==================== */ -/* 标题样式 */ -QLabel[text="规程编辑器"] { - font-size: 16px; - font-weight: bold; - color: #2c3e50; - padding: 10px; - background-color: #ecf0f1; - border-radius: 5px; - margin: 5px; +/* 时间显示 - 危险状态 */ +QLabel#timeDisplay[danger="true"] { + color: #DC2626; + background-color: #FEF2F2; + border-color: #FECACA; } -/* 分组容器样式 */ -QWidget[class="info_group"] { - background-color: #f8f9fa; - border: 1px solid #dee2e6; - border-radius: 5px; - padding: 10px; - margin: 5px; +/* 步骤详情面板 */ +QWidget#stepDetailPanel { + background-color: #FFFFFF; + border: 1px solid #E5E7EB; + border-radius: 12px; + padding: 20px; + margin: 12px; } -QWidget[class="steps_group"] { - background-color: #f8f9fa; - border: 1px solid #dee2e6; - border-radius: 5px; - padding: 10px; - margin: 5px; +/* 步骤详情标题 */ +QLabel#stepDetailTitle { + font-size: 16px; + font-weight: 600; + color: #1F2937; + margin-bottom: 16px; + padding-bottom: 8px; + border-bottom: 2px solid #E5E7EB; } -/* 分组标题样式 */ -QLabel[text="基本信息"], QLabel[text="步骤列表"] { - font-weight: bold; - color: #3498db; - margin-bottom: 5px; +/* 步骤描述 */ +QLabel#stepDescription { + font-size: 14px; + color: #374151; + line-height: 1.6; + padding: 12px 16px; + background-color: #F8FAFC; + border: 1px solid #E5E7EB; + border-radius: 8px; + word-wrap: break-word; } -/* 添加步骤按钮样式 */ -QPushButton[text="添加步骤"] { - background-color: #28a745; - color: white; - border: none; - padding: 5px 10px; - border-radius: 3px; +/* 执行日志 */ +QTextEdit#executionLog { + background-color: #1F2937; + color: #F9FAFB; + border: 1px solid #374151; + border-radius: 8px; + font-family: "Consolas", "Monaco", "Courier New", monospace; font-size: 12px; + padding: 12px; + line-height: 1.4; } -QPushButton[text="添加步骤"]:hover { - background-color: #218838; +/* 日志滚动条 */ +QTextEdit#executionLog QScrollBar:vertical { + background-color: #374151; + width: 12px; + border-radius: 6px; } -/* 删除步骤按钮样式 */ -QPushButton[text="删除步骤"] { - background-color: #dc3545; - color: white; - border: none; - padding: 5px 10px; - border-radius: 3px; - font-size: 12px; +QTextEdit#executionLog QScrollBar::handle:vertical { + background-color: #6B7280; + border-radius: 6px; + min-height: 30px; } -QPushButton[text="删除步骤"]:hover { - background-color: #c82333; +QTextEdit#executionLog QScrollBar::handle:vertical:hover { + background-color: #9CA3AF; } -/* 保存规程按钮样式 */ -QPushButton[text="保存规程"] { - background-color: #007bff; - color: white; +/* 操作历史表格 */ +QTableWidget#operationHistory { + background-color: #FFFFFF; + alternate-background-color: #F8FAFC; + gridline-color: #F3F4F6; + border: 1px solid #E5E7EB; + border-radius: 8px; + selection-background-color: #EBF8FF; + selection-color: #1E40AF; + outline: none; + font-size: 13px; +} + +QTableWidget#operationHistory::item { + padding: 12px 16px; border: none; - padding: 10px 20px; - border-radius: 5px; - font-size: 14px; - font-weight: bold; + background-color: transparent; } -QPushButton[text="保存规程"]:hover { - background-color: #0056b3; +QTableWidget#operationHistory::item:selected { + background-color: #EBF8FF; + color: #1E40AF; } -/* 取消按钮样式 */ -QPushButton[text="❌ 取消"] { - background-color: #6c757d; - color: white; +QTableWidget#operationHistory::item:hover { + background-color: #F8FAFC; +} + +/* 操作历史表头 */ +QTableWidget#operationHistory QHeaderView::section { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #F9FAFB, stop:1 #F3F4F6); + color: #374151; + padding: 16px 12px; border: none; - padding: 10px 20px; - border-radius: 5px; - font-size: 14px; - font-weight: bold; + border-right: 1px solid #E5E7EB; + border-bottom: 2px solid #E5E7EB; + font-weight: 600; + font-size: 13px; + text-align: center; } -QPushButton[text="❌ 取消"]:hover { - background-color: #5a6268; +/* 快捷操作面板 */ +QWidget#quickActionPanel { + background-color: #F8FAFC; + border: 1px solid #E5E7EB; + border-radius: 8px; + padding: 16px; + margin: 8px 0; } -/* ==================== 规程执行界面样式 ==================== */ -/* 规程信息容器 */ -QWidget#procedureInfoContainer { - background-color: #ffffff; - border: 2px solid #dee2e6; - border-radius: 10px; - padding: 20px; - margin: 10px; +/* 快捷操作标题 */ +QLabel#quickActionTitle { + font-size: 14px; + font-weight: 600; + color: #374151; + margin-bottom: 12px; } -/* 信息分组组件 */ -QWidget#infoGroupWidget { - background-color: #f8f9fa; - border: 1px solid #dee2e6; - border-radius: 8px; - padding: 15px; - margin: 5px; - min-width: 200px; - min-height: 80px; +/* 快捷操作按钮组 */ +QWidget#quickActionButtons { + background-color: transparent; } -/* 规程名称分组 */ -QWidget#procedureNameGroup { - border-color: #343a40; +/* 小型按钮样式 */ +QPushButton#smallBtn { + padding: 8px 12px; + font-size: 12px; + min-width: 60px; + min-height: 28px; + border-radius: 6px; } -/* 规程编号分组 */ -QWidget#procedureNumberGroup { - border-color: #343a40; +/* 图标按钮样式 */ +QPushButton#iconBtn { + padding: 10px; + min-width: 40px; + min-height: 40px; + border-radius: 8px; + font-size: 16px; } -/* 规程类型分组 */ -QWidget#procedureTypeGroup { - border-color: #343a40; +QPushButton#iconBtn:hover { + transform: scale(1.05); } -/* 测试用例分组 */ -QWidget#testCaseGroup { - border-color: #343a40; +/* 浮动操作按钮 */ +QPushButton#fabBtn { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #3B82F6, stop:1 #2563EB); + border: none; + border-radius: 28px; + color: #FFFFFF; + font-size: 18px; + font-weight: 600; + min-width: 56px; + min-height: 56px; + padding: 0; } -/* 用例编号分组 */ -QWidget#caseNumberGroup { - border-color: #343a40; +QPushButton#fabBtn:hover { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #2563EB, stop:1 #1D4ED8); } -/* 工况描述分组 */ -QWidget#conditionDescriptionGroup { - border-color: #343a40; +QPushButton#fabBtn:pressed { + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #1D4ED8, stop:1 #1E40AF); } -/* 信息标签样式 */ -QLabel#infoGroupLabel { - font-weight: bold; - font-size: 14px; - color: #212529; - margin-bottom: 8px; - padding: 5px 0px; +/* 通知横幅 */ +QWidget#notificationBanner { + background-color: #EBF8FF; + border: 1px solid #93C5FD; + border-radius: 8px; + padding: 12px 16px; + margin: 8px 0; } -/* 规程名称标签 */ -QLabel#procedureNameLabel { - color: #212529; +/* 通知横幅 - 成功 */ +QWidget#notificationBanner[type="success"] { + background-color: #ECFDF5; + border-color: #BBF7D0; } -/* 规程编号标签 */ -QLabel#procedureNumberLabel { - color: #212529; +/* 通知横幅 - 警告 */ +QWidget#notificationBanner[type="warning"] { + background-color: #FEF3C7; + border-color: #FCD34D; } -/* 规程类型标签 */ -QLabel#procedureTypeLabel { - color: #212529; +/* 通知横幅 - 错误 */ +QWidget#notificationBanner[type="error"] { + background-color: #FEF2F2; + border-color: #FECACA; } -/* 测试用例标签 */ -QLabel#testCaseLabel { - color: #212529; +/* 通知文本 */ +QLabel#notificationText { + font-size: 14px; + font-weight: 500; + color: #374151; } -/* 用例编号标签 */ -QLabel#caseNumberLabel { - color: #212529; +/* 通知文本 - 成功 */ +QLabel#notificationText[type="success"] { + color: #166534; } -/* 工况描述标签 */ -QLabel#conditionDescriptionLabel { - color: #212529; +/* 通知文本 - 警告 */ +QLabel#notificationText[type="warning"] { + color: #92400E; } -/* 信息值样式 */ -QLabel#infoGroupValue { - color: #212529; - font-weight: bold; - font-size: 16px; - padding: 8px; - background-color: #ffffff; - border-radius: 6px; - border: 1px solid #dee2e6; - min-height: 20px; +/* 通知文本 - 错误 */ +QLabel#notificationText[type="error"] { + color: #991B1B; } -/* 工况描述值样式 */ -QLabel#descriptionValue { - color: #495057; - font-size: 14px; - padding: 10px; - background-color: #ffffff; - border-radius: 6px; - border: 1px solid #dee2e6; - line-height: 1.4; +/* 数据统计卡片 */ +QWidget#statsCard { + background-color: #FFFFFF; + border: 1px solid #E5E7EB; + border-radius: 12px; + padding: 20px; + margin: 8px; + min-width: 200px; } -/* 状态标签样式 */ -QLabel#statusLabel { - color: #212529; - font-weight: bold; - font-size: 16px; +/* 统计数值 */ +QLabel#statsValue { + font-size: 32px; + font-weight: 700; + color: #1F2937; + text-align: center; } -/* 倒计时标签样式 */ -QLabel#countdownLabel { - color: #212529; - font-weight: bold; - font-size: 16px; +/* 统计标签 */ +QLabel#statsLabel { + font-size: 14px; + font-weight: 500; + color: #6B7280; + text-align: center; + margin-top: 8px; } -/* 倒计时标签状态样式 */ -QLabel#countdownLabel[timeRemaining="low"] { - color: #dc3545; +/* 统计变化指示器 */ +QLabel#statsChange { + font-size: 12px; + font-weight: 600; + padding: 4px 8px; + border-radius: 12px; + text-align: center; + margin-top: 8px; } -QLabel#countdownLabel[timeRemaining="medium"] { - color: #fd7e14; +/* 统计变化 - 上升 */ +QLabel#statsChange[trend="up"] { + background-color: #ECFDF5; + color: #166534; } -QLabel#countdownLabel[timeRemaining="high"] { - color: #212529; +/* 统计变化 - 下降 */ +QLabel#statsChange[trend="down"] { + background-color: #FEF2F2; + color: #991B1B; } -QLabel#countdownLabel[timeRemaining="completed"] { - color: #28a745; +/* 统计变化 - 持平 */ +QLabel#statsChange[trend="stable"] { + background-color: #F3F4F6; + color: #6B7280; } \ No newline at end of file diff --git a/Static/Profibus.qss b/Static/Profibus.qss index 5ea1d0b..ee0b406 100644 --- a/Static/Profibus.qss +++ b/Static/Profibus.qss @@ -299,7 +299,7 @@ QPushButton#closeButton, QPushButton#minButton, QPushButton#startActionBtn{ } -QPushButton#confirmButton, QPushButton#exitButton{ +QPushButton#confirmButton{ width: 54.75px; diff --git a/Static/control.png b/Static/control.png deleted file mode 100644 index de98c81..0000000 --- a/Static/control.png +++ /dev/null @@ -1,4 +0,0 @@ -# 这是控制系统图标的占位符文件 -# 请替换为实际的PNG图标文件 -# 建议尺寸: 26x26 像素 -# 颜色: 灰色调,与其他图标风格一致 \ No newline at end of file diff --git a/Static/controlH.png b/Static/controlH.png deleted file mode 100644 index a820dd1..0000000 --- a/Static/controlH.png +++ /dev/null @@ -1,4 +0,0 @@ -# 这是控制系统高亮图标的占位符文件 -# 请替换为实际的PNG图标文件 -# 建议尺寸: 26x26 像素 -# 颜色: 蓝色调 (#2277EF),与其他高亮图标风格一致 \ No newline at end of file diff --git a/UI/Main/Main.py b/UI/Main/Main.py index 452c33b..78addaf 100644 --- a/UI/Main/Main.py +++ b/UI/Main/Main.py @@ -28,6 +28,7 @@ from utils.DBModels.InitParameterDB import InitParameterDB from UI.ProfibusWidgets.ProfibusWindow import ProfibusWidgets from UI.ProcedureManager.ProcedureManager import ProcedureManager from UI.ControlManage.ControlWidget import getControlWidget +import qtawesome class CommonHelper: def __init__(self): @@ -132,7 +133,8 @@ class MainWindow(QMainWindow): self.varManageTabWidget.addTab(self.rpcVarTableWidget, '远程通讯') #添加导入变量按钮 - self.importVarButton = QPushButton(QIcon('./Static/import.png'), '导入变量') + self.importVarButton = QPushButton('导入变量') + self.importVarButton.setIcon(qtawesome.icon('fa5s.file-import', color = '#059669')) self.importVarButton.setObjectName('importBtn') self.importVarButton.setIconSize(QSize(22, 22)) self.importVarButton.setFlat(True) diff --git a/UI/Main/MainTop.py b/UI/Main/MainTop.py index 3d7d189..f5308e5 100644 --- a/UI/Main/MainTop.py +++ b/UI/Main/MainTop.py @@ -46,7 +46,7 @@ class MainTop(QtWidgets.QWidget): self.closeBtn.setObjectName("closeBtn") self.iconLabol.setPixmap(QPixmap('./Static/zhjt.png').scaled(50,50)) - self.titleLabel.setText("信号发生装置") + self.titleLabel.setText("数字化临措平台") self.closeBtn.clicked.connect(self.MainWindow.close) self.minBtn.clicked.connect(self.MainWindow.showMinimized) diff --git a/UI/ProcedureManager/HistoryViewer.py b/UI/ProcedureManager/HistoryViewer.py index 0c15abb..cae3793 100644 --- a/UI/ProcedureManager/HistoryViewer.py +++ b/UI/ProcedureManager/HistoryViewer.py @@ -85,7 +85,7 @@ class HistoryViewerWidget(QWidget): def setupTableDisplay(self, table): """设置表格显示属性""" table.setWordWrap(True) - table.setAlternatingRowColors(True) + table.setAlternatingRowColors(False) table.setSortingEnabled(True) header = table.horizontalHeader() diff --git a/UI/ProcedureManager/KeywordManager.py b/UI/ProcedureManager/KeywordManager.py index ae9a3cb..5194396 100644 --- a/UI/ProcedureManager/KeywordManager.py +++ b/UI/ProcedureManager/KeywordManager.py @@ -221,7 +221,7 @@ class KeywordManagerWidget(QWidget): header.setSectionResizeMode(4, QHeaderView.ResizeToContents) # 创建时间 # 设置交替行颜色 - self.tableView.setAlternatingRowColors(True) + self.tableView.setAlternatingRowColors(False) # 设置表格不可编辑 self.tableView.setEditTriggers(QTableView.NoEditTriggers) diff --git a/UI/ProcedureManager/ProcedureEditor.py b/UI/ProcedureManager/ProcedureEditor.py index 3a03afb..88e23ce 100644 --- a/UI/ProcedureManager/ProcedureEditor.py +++ b/UI/ProcedureManager/ProcedureEditor.py @@ -207,7 +207,7 @@ class ProcedureEditor(QWidget): # 设置表格属性 self.stepsTable.setSelectionBehavior(QAbstractItemView.SelectRows) self.stepsTable.setEditTriggers(QAbstractItemView.AllEditTriggers) # 允许所有方式编辑 - self.stepsTable.setAlternatingRowColors(True) + self.stepsTable.setAlternatingRowColors(False) # 设置列宽 header = self.stepsTable.horizontalHeader() diff --git a/UI/ProcedureManager/StepExecutor.py b/UI/ProcedureManager/StepExecutor.py index c7aac1a..98f0932 100644 --- a/UI/ProcedureManager/StepExecutor.py +++ b/UI/ProcedureManager/StepExecutor.py @@ -194,7 +194,7 @@ class StepExecutor(QWidget): self.tableView.setSelectionBehavior(QTableView.SelectRows) # 设置表格显示优化 - self.tableView.setAlternatingRowColors(True) # 交替行颜色 + self.tableView.setAlternatingRowColors(False) # 交替行颜色 self.tableView.setShowGrid(True) # 显示网格线 self.tableView.setGridStyle(Qt.SolidLine) # 实线网格 self.tableView.setSortingEnabled(False) # 禁用排序避免干扰执行顺序 diff --git a/UI/ProjectManages/ProjectModel.py b/UI/ProjectManages/ProjectModel.py index 1048c0b..6273858 100644 --- a/UI/ProjectManages/ProjectModel.py +++ b/UI/ProjectManages/ProjectModel.py @@ -258,6 +258,7 @@ class ProjectButtonDelegate(QItemDelegate): modelLists = ['ModbusTcpMasterTable', 'ModbusTcpSlaveTable', 'ModbusRtuMasterTable', \ 'ModbusRtuSlaveTable', 'HartTable', 'TcRtdTable', 'AnalogTable', 'HartSimulateTable', 'userTable'] for l in modelLists: + # print(l) Globals.getValue(l).model.initTable() QtWidgets.QApplication.processEvents() diff --git a/UI/ProjectManages/ProjectWidget.py b/UI/ProjectManages/ProjectWidget.py index cfb6fbc..c92fa3a 100644 --- a/UI/ProjectManages/ProjectWidget.py +++ b/UI/ProjectManages/ProjectWidget.py @@ -2,6 +2,7 @@ from PyQt5 import QtCore, QtWidgets from PyQt5.QtCore import QSize, Qt from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import QSplitter, QPushButton +import qtawesome as qta from .ProjectTable import ProjectTableView from model.ProjectModel.ProjectManage import ProjectManage @@ -11,22 +12,118 @@ class ProjectWidgets(QtWidgets.QWidget): super(ProjectWidgets, self).__init__() self.setAttribute(Qt.WA_StyledBackground, True) self.setupUi() + + def setupButtonIcon(self, button, icon_name, color): + """设置按钮图标,支持不同状态的颜色变化""" + # 正常状态图标 + normal_icon = qta.icon(icon_name, color=color) + + # 悬停状态图标(稍微亮一些) + hover_color = self.lightenColor(color, 0.2) + hover_icon = qta.icon(icon_name, color=hover_color) + + # 按下状态图标(稍微暗一些) + pressed_color = self.darkenColor(color, 0.2) + pressed_icon = qta.icon(icon_name, color=pressed_color) + + # 设置图标 + button.setIcon(normal_icon) + + # 存储不同状态的图标,用于状态切换 + button._normal_icon = normal_icon + button._hover_icon = hover_icon + button._pressed_icon = pressed_icon + + # 连接事件 + button.enterEvent = lambda event: self.onButtonEnter(button, event) + button.leaveEvent = lambda event: self.onButtonLeave(button, event) + button.mousePressEvent = lambda event: self.onButtonPress(button, event) + button.mouseReleaseEvent = lambda event: self.onButtonRelease(button, event) + + def lightenColor(self, color, factor): + """使颜色变亮""" + if color.startswith('#'): + # 十六进制颜色 + r = int(color[1:3], 16) + g = int(color[3:5], 16) + b = int(color[5:7], 16) + + r = min(255, int(r + (255 - r) * factor)) + g = min(255, int(g + (255 - g) * factor)) + b = min(255, int(b + (255 - b) * factor)) + + return f"#{r:02x}{g:02x}{b:02x}" + return color + + def darkenColor(self, color, factor): + """使颜色变暗""" + if color.startswith('#'): + # 十六进制颜色 + r = int(color[1:3], 16) + g = int(color[3:5], 16) + b = int(color[5:7], 16) + + r = max(0, int(r * (1 - factor))) + g = max(0, int(g * (1 - factor))) + b = max(0, int(b * (1 - factor))) + + return f"#{r:02x}{g:02x}{b:02x}" + return color + + def onButtonEnter(self, button, event): + """按钮鼠标进入事件""" + if hasattr(button, '_hover_icon'): + button.setIcon(button._hover_icon) + # 调用原始的enterEvent + QPushButton.enterEvent(button, event) + + def onButtonLeave(self, button, event): + """按钮鼠标离开事件""" + if hasattr(button, '_normal_icon'): + button.setIcon(button._normal_icon) + # 调用原始的leaveEvent + QPushButton.leaveEvent(button, event) + + def onButtonPress(self, button, event): + """按钮鼠标按下事件""" + if hasattr(button, '_pressed_icon'): + button.setIcon(button._pressed_icon) + # 调用原始的mousePressEvent + QPushButton.mousePressEvent(button, event) + + def onButtonRelease(self, button, event): + """按钮鼠标释放事件""" + # 检查鼠标是否还在按钮上 + if button.rect().contains(event.pos()): + if hasattr(button, '_hover_icon'): + button.setIcon(button._hover_icon) + else: + if hasattr(button, '_normal_icon'): + button.setIcon(button._normal_icon) + # 调用原始的mouseReleaseEvent + QPushButton.mouseReleaseEvent(button, event) def setupUi(self): - self.createBtn = QPushButton(QIcon('./Static/add.png'), '新建工程') + # 新建工程按钮 + self.createBtn = QPushButton('新建工程') self.createBtn.setObjectName('createBtn') - self.createBtn.setIconSize(QSize(22, 22)) + self.createBtn.setIconSize(QSize(18, 18)) self.createBtn.clicked.connect(self.createProject) + self.setupButtonIcon(self.createBtn, 'fa5s.plus', '#2277EF') - self.importBtn = QPushButton(QIcon('./Static/import.png'), '导入工程') + # 导入工程按钮 + self.importBtn = QPushButton('导入工程') self.importBtn.setObjectName('importBtn') - self.importBtn.setIconSize(QSize(22, 22)) + self.importBtn.setIconSize(QSize(18, 18)) self.importBtn.clicked.connect(self.importProject) + self.setupButtonIcon(self.importBtn, 'fa5s.file-import', '#059669') - self.exportBtn = QPushButton(QIcon('./Static/export.png'), '导出工程') + # 导出工程按钮 + self.exportBtn = QPushButton('导出工程') self.exportBtn.setObjectName('exportBtn') - self.exportBtn.setIconSize(QSize(22, 22)) + self.exportBtn.setIconSize(QSize(18, 18)) self.exportBtn.clicked.connect(self.exportPorject) + self.setupButtonIcon(self.exportBtn, 'fa5s.file-export', '#7C3AED') self.projectView = ProjectTableView() self.projectView.setObjectName('projectView') diff --git a/UI/Setting/RTUSetting.py b/UI/Setting/RTUSetting.py index 32ab84f..9b7cb40 100644 --- a/UI/Setting/RTUSetting.py +++ b/UI/Setting/RTUSetting.py @@ -1,7 +1,7 @@ from PyQt5.QtCore import (QCoreApplication, Qt) -from PyQt5.QtWidgets import (QComboBox, QGridLayout, QLabel, - QLineEdit, QPushButton, QSizePolicy, QSpacerItem, QListView, - QWidget, QMessageBox, QListView) +from PyQt5.QtWidgets import (QComboBox, QVBoxLayout, QHBoxLayout, QLabel, + QLineEdit, QPushButton, QListView, + QWidget, QMessageBox) from utils.DBModels.ProtocolModel import RTUSetting @@ -12,7 +12,6 @@ class CustomBox(QComboBox): self.setCursor(Qt.PointingHandCursor) self.setView(QListView()) - def showPopup(self): QComboBox.showPopup(self) pop = self.children()[1] @@ -23,185 +22,187 @@ class RTUSettingWidget(QWidget): def __init__(self, rtuType): super(RTUSettingWidget, self).__init__() self.rtuType = rtuType - self.gridLayout_2 = QGridLayout(self) - self.gridLayout_2.setObjectName("gridLayout_2") - self.gridLayout = QGridLayout() - self.gridLayout.setObjectName("gridLayout") - self.horizontalSpacer_3 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) - - self.gridLayout.addItem(self.horizontalSpacer_3, 5, 0, 1, 2) + self.setObjectName("RTUSettingWidget") + self.setupUI() + def setupUI(self): + # 主布局 - 垂直布局 + main_layout = QVBoxLayout(self) + main_layout.setContentsMargins(0, 0, 0, 0) + main_layout.setSpacing(7) + + # 第一行:端口号和波特率 + row1_layout = QHBoxLayout() + row1_layout.setSpacing(15) + + # 端口号列 + port_column = QVBoxLayout() + port_column.setSpacing(4) + self.label = QLabel('端口号') + self.label.setObjectName("setlabel") + self.portEdit = QLineEdit() + self.portEdit.setObjectName("setEdit") + port_column.addWidget(self.label) + port_column.addWidget(self.portEdit) + + # 波特率列 + baud_column = QVBoxLayout() + baud_column.setSpacing(4) + self.label_5 = QLabel('波特率') + self.label_5.setObjectName("setlabel") + self.baudrateEdit = QLineEdit() + self.baudrateEdit.setObjectName("setEdit") + baud_column.addWidget(self.label_5) + baud_column.addWidget(self.baudrateEdit) + + row1_layout.addLayout(port_column) + row1_layout.addLayout(baud_column) + main_layout.addLayout(row1_layout) + + # 第二行:字节长度和停止位 + row2_layout = QHBoxLayout() + row2_layout.setSpacing(15) + + # 字节长度列 + byte_column = QVBoxLayout() + byte_column.setSpacing(4) + self.label_2 = QLabel('字节长度') + self.label_2.setObjectName("setlabel") self.byteSizeBox = CustomBox() self.byteSizeBox.addItem("8") self.byteSizeBox.addItem("7") self.byteSizeBox.setObjectName("setBox") - - self.gridLayout.addWidget(self.byteSizeBox, 4, 1, 1, 1) - - self.label = QLabel(self) - self.label.setObjectName("setlabel") - - self.gridLayout.addWidget(self.label, 0, 0, 1, 1) - - self.label_4 = QLabel(self) + byte_column.addWidget(self.label_2) + byte_column.addWidget(self.byteSizeBox) + + # 停止位列 + stop_column = QVBoxLayout() + stop_column.setSpacing(4) + self.label_4 = QLabel('停止位') self.label_4.setObjectName("setlabel") - - self.gridLayout.addWidget(self.label_4, 8, 0, 1, 1) - - self.baudrateEdit = QLineEdit(self) - self.baudrateEdit.setObjectName("setEdit") - - self.gridLayout.addWidget(self.baudrateEdit, 2, 1, 1, 1) - self.stopbitsBox = CustomBox() self.stopbitsBox.addItem("1") self.stopbitsBox.addItem("2") self.stopbitsBox.setObjectName("setBox") - - self.gridLayout.addWidget(self.stopbitsBox, 8, 1, 1, 1) - - self.freEdit = QLineEdit(self) - self.freEdit.setObjectName("setEdit") - - self.gridLayout.addWidget(self.freEdit, 10, 1, 1, 1) - - self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) - - self.gridLayout.addItem(self.horizontalSpacer, 1, 0, 1, 2) - - self.label_6 = QLabel(self) - self.label_6.setObjectName("setlabel") - - self.gridLayout.addWidget(self.label_6, 10, 0, 1, 1) - - self.label_3 = QLabel(self) + stop_column.addWidget(self.label_4) + stop_column.addWidget(self.stopbitsBox) + + row2_layout.addLayout(byte_column) + row2_layout.addLayout(stop_column) + main_layout.addLayout(row2_layout) + + # 第三行:奇偶校验(单独一行) + parity_layout = QVBoxLayout() + parity_layout.setSpacing(4) + self.label_3 = QLabel('奇偶校验') self.label_3.setObjectName("setlabel") - - self.gridLayout.addWidget(self.label_3, 6, 0, 1, 1) - - self.label_5 = QLabel(self) - self.label_5.setObjectName("setlabel") - - self.gridLayout.addWidget(self.label_5, 2, 0, 1, 1) - - self.horizontalSpacer_4 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) - - self.gridLayout.addItem(self.horizontalSpacer_4, 7, 0, 1, 2) - - self.portEdit = QLineEdit(self) - self.portEdit.setObjectName("setEdit") - - self.gridLayout.addWidget(self.portEdit, 0, 1, 1, 1) - - self.label_2 = QLabel(self) - self.label_2.setObjectName("setlabel") - - self.gridLayout.addWidget(self.label_2, 4, 0, 1, 1) - self.parityBox = CustomBox() self.parityBox.addItem("N 无") self.parityBox.addItem("O 奇") self.parityBox.addItem("E 偶") self.parityBox.setObjectName("setBox") - - self.gridLayout.addWidget(self.parityBox, 6, 1, 1, 1) - - self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) - - self.gridLayout.addItem(self.horizontalSpacer_2, 3, 0, 1, 2) - - self.horizontalSpacer_5 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) - - self.gridLayout.addItem(self.horizontalSpacer_5, 9, 0, 1, 2) - + parity_layout.addWidget(self.label_3) + parity_layout.addWidget(self.parityBox) + main_layout.addLayout(parity_layout) + + # 第四行:通信频率和起始值 + row4_layout = QHBoxLayout() + row4_layout.setSpacing(15) + + # 通信频率列 + freq_column = QVBoxLayout() + freq_column.setSpacing(4) + self.label_6 = QLabel('通信频率') + self.label_6.setObjectName("setlabel") + self.freEdit = QLineEdit() + self.freEdit.setObjectName("setEdit") + freq_column.addWidget(self.label_6) + freq_column.addWidget(self.freEdit) + + # 起始值列 + offset_column = QVBoxLayout() + offset_column.setSpacing(4) + self.label_7 = QLabel('起始值') + self.label_7.setObjectName('setlabel') self.offsetBox = CustomBox() self.offsetBox.addItem("1") self.offsetBox.addItem("0") self.offsetBox.setObjectName("setBox") - - self.gridLayout.addItem(QSpacerItem(40, 20), 11, 0, 1, 2) - - self.label_7 = QLabel('起始值') - self.label_7.setObjectName('setlabel') - self.gridLayout.addWidget(self.label_7, 12, 0, 1, 1) - - self.gridLayout.addWidget(self.offsetBox, 12, 1, 1, 1) - - self.gridLayout.addItem(QSpacerItem(40, 20), 13, 0, 1, 2) - - - self.gridLayout_2.addLayout(self.gridLayout, 3, 5, 2, 2) - - self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) - - self.gridLayout_2.addItem(self.verticalSpacer, 0, 1, 3, 12) - - self.saveButton = QPushButton() - self.saveButton.setObjectName('setButton') - - self.gridLayout.addWidget(self.saveButton, 15, 1, 1, 1) - - self.horizontalSpacer_6 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) - - self.gridLayout_2.addItem(self.horizontalSpacer_6, 7, 0, 3, 5) - - self.horizontalSpacer_7 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) - - self.gridLayout_2.addItem(self.horizontalSpacer_7, 7, 2, 3, 5) - - self.verticalSpacer_2 = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) - - self.gridLayout_2.addItem(self.verticalSpacer_2, 7, 0, 3, 5) - - - self.label.setText(QCoreApplication.translate("self", u"\u7aef\u53e3\u53f7", None)) - self.label_4.setText(QCoreApplication.translate("self", u"\u505c\u6b62\u4f4d", None)) - - self.label_6.setText(QCoreApplication.translate("self", u"\u901a\u4fe1\u9891\u7387", None)) - self.label_3.setText(QCoreApplication.translate("self", u"\u5947\u5076\u6821\u9a8c", None)) - self.label_5.setText(QCoreApplication.translate("self", u"\u6ce2\u7279\u7387", None)) - self.label_2.setText(QCoreApplication.translate("self", u"\u5b57\u8282\u957f\u5ea6", None)) - - self.saveButton.setText(QCoreApplication.translate("self", u"\u4fdd\u5b58", None)) - - self.saveButton.clicked.connect(self.saveSetting) - - - # self.setupUi() - - # retranslateUi - - def setupUI(self): + offset_column.addWidget(self.label_7) + offset_column.addWidget(self.offsetBox) + + row4_layout.addLayout(freq_column) + row4_layout.addLayout(offset_column) + main_layout.addLayout(row4_layout) + + # 保存按钮 + self.saveButton = QPushButton('保存') if self.rtuType == 'master': - query = RTUSetting.get_by_id(1) + self.saveButton.setObjectName('rtuSaveButton') else: - query = RTUSetting.get_by_id(2) - port = str(query.port) - byteSize = str(query.byteSize) - baudrate = str(query.baudrate) - stopbits = str(query.stopbits) - parity = str(query.parity) - frequency = str(query.frequency) - offset = str(query.offset) - - self.portEdit.setText(port) - self.byteSizeBox.setCurrentText(byteSize) - self.baudrateEdit.setText(baudrate) - self.stopbitsBox.setCurrentText(stopbits) - self.freEdit.setText(frequency) - self.offsetBox.setCurrentText(offset) - self.parityBox.setCurrentText(parity) + self.saveButton.setObjectName('setButton') + self.saveButton.clicked.connect(self.saveSetting) + main_layout.addWidget(self.saveButton) + + # 添加弹性空间 + main_layout.addStretch() + + def loadSettings(self): + """加载设置数据""" + try: + if self.rtuType == 'master': + query = RTUSetting.get_by_id(1) + else: + query = RTUSetting.get_by_id(2) + + port = str(query.port) + byteSize = str(query.byteSize) + baudrate = str(query.baudrate) + stopbits = str(query.stopbits) + parity = str(query.parity) + frequency = str(query.frequency) + offset = str(query.offset) + + self.portEdit.setText(port) + self.byteSizeBox.setCurrentText(byteSize) + self.baudrateEdit.setText(baudrate) + self.stopbitsBox.setCurrentText(stopbits) + self.freEdit.setText(frequency) + self.offsetBox.setCurrentText(offset) + self.parityBox.setCurrentText(parity) + except Exception as e: + print(f"加载RTU设置失败: {e}") + # 设置默认值 + self.portEdit.setText("COM1") + self.byteSizeBox.setCurrentText("8") + self.baudrateEdit.setText("9600") + self.stopbitsBox.setCurrentText("1") + self.freEdit.setText("1") + self.offsetBox.setCurrentText("1") + self.parityBox.setCurrentText("N 无") def saveSetting(self): - port = self.portEdit.text() - byteSize = self.byteSizeBox.currentText() - baudrate = self.baudrateEdit.text() - stopbits = self.stopbitsBox.currentText() - parity = self.parityBox.currentText() - frequency = self.freEdit.text() - offset = self.offsetBox.currentText() - if self.rtuType == 'master': - RTUSetting.update(port = port, byteSize = byteSize, baudrate = baudrate, stopbits = stopbits, parity = parity, frequency = frequency, offset = offset).where(RTUSetting.tcpType == 'master').execute() - else: - RTUSetting.update(port = port, byteSize = byteSize, baudrate = baudrate, stopbits = stopbits, parity = parity, frequency = frequency, offset = offset).where(RTUSetting.tcpType == 'slave').execute() - QMessageBox.information(self, 'Sucess', '保存成功') \ No newline at end of file + """保存设置""" + try: + port = self.portEdit.text() + byteSize = self.byteSizeBox.currentText() + baudrate = self.baudrateEdit.text() + stopbits = self.stopbitsBox.currentText() + parity = self.parityBox.currentText() + frequency = self.freEdit.text() + offset = self.offsetBox.currentText() + + if self.rtuType == 'master': + RTUSetting.update(port=port, byteSize=byteSize, baudrate=baudrate, + stopbits=stopbits, parity=parity, frequency=frequency, + offset=offset).where(RTUSetting.tcpType == 'master').execute() + else: + RTUSetting.update(port=port, byteSize=byteSize, baudrate=baudrate, + stopbits=stopbits, parity=parity, frequency=frequency, + offset=offset).where(RTUSetting.tcpType == 'slave').execute() + + # 创建消息框 + QMessageBox.information(self, '保存成功', f'RTU{self.rtuType}站配置已保存!') + + except Exception as e: + QMessageBox.critical(self, '保存失败', f'保存RTU设置时发生错误:{str(e)}') \ No newline at end of file diff --git a/UI/Setting/Setting.py b/UI/Setting/Setting.py index 9341c30..ae2f9f9 100644 --- a/UI/Setting/Setting.py +++ b/UI/Setting/Setting.py @@ -20,10 +20,10 @@ class SettingWidget(QWidget): self.rtuSlaveSettingWidget = RTUSettingWidget('slave') self.remoteConnectSettingWidget = RemoteConnectSettingWidget() - self.tcpMasterSettingWidget.setupUI() - self.tcpSlaveSettingWidget.setupUI() - self.rtuMasterSettingWidget.setupUI() - self.rtuSlaveSettingWidget.setupUI() + self.tcpMasterSettingWidget.loadSettings() + self.tcpSlaveSettingWidget.loadSettings() + self.rtuMasterSettingWidget.loadSettings() + self.rtuSlaveSettingWidget.loadSettings() # 分组布局 self.tcpGroup = QGroupBox() self.tcpLayout = QVBoxLayout() diff --git a/UI/Setting/TCPSetting.py b/UI/Setting/TCPSetting.py index 8a3e67b..1217199 100644 --- a/UI/Setting/TCPSetting.py +++ b/UI/Setting/TCPSetting.py @@ -1,6 +1,6 @@ from PyQt5.QtCore import (QCoreApplication, Qt) -from PyQt5.QtWidgets import (QGridLayout, QLabel, QLineEdit, - QPushButton, QSizePolicy, QSpacerItem, QWidget, QComboBox, QMessageBox, QSplitter, QListView) +from PyQt5.QtWidgets import (QVBoxLayout, QLabel, QLineEdit, + QPushButton, QWidget, QComboBox, QMessageBox, QListView) from utils.DBModels.ProtocolModel import TCPSetting @@ -10,7 +10,6 @@ class CustomBox(QComboBox): self.setCursor(Qt.PointingHandCursor) self.setView(QListView()) - def showPopup(self): super(CustomBox, self).showPopup() pop = self.children()[1] @@ -18,134 +17,105 @@ class CustomBox(QComboBox): class TCPSettingWidget(QWidget): - BORDER_WIDTH = 5 - def __init__(self, tcpType): super(TCPSettingWidget, self).__init__() self.tcpType = tcpType - self.gridLayout_2 = QGridLayout(self) - self.gridLayout_2.setObjectName("gridLayout_2") - self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) + self.setObjectName("TCPSettingWidget") + self.setupUI() - self.gridLayout_2.addItem(self.verticalSpacer, 0, 1, 3, 12) + def setupUI(self): + # 主布局 - 垂直布局 + main_layout = QVBoxLayout(self) + main_layout.setContentsMargins(0, 0, 0, 0) + main_layout.setSpacing(8) - self.gridLayout = QGridLayout() - self.gridLayout.setObjectName("gridLayout") - self.label = QLabel(self) + # IP地址 + self.label = QLabel('IP地址') self.label.setObjectName("setlabel") - self.label.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignVCenter) - - self.gridLayout.addWidget(self.label, 0, 0, 1, 1) - - self.horizontalSpacer_3 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) - - self.gridLayout.addItem(self.horizontalSpacer_3, 2, 0, 1, 4) - - self.horizontalSpacer_4 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) - - self.gridLayout.addItem(self.horizontalSpacer_4, 5, 0, 1, 4) - - self.ipEdit = QLineEdit(self) + self.ipEdit = QLineEdit() self.ipEdit.setObjectName("setEdit") + main_layout.addWidget(self.label) + main_layout.addWidget(self.ipEdit) - self.gridLayout.addWidget(self.ipEdit, 1, 0, 1, 3) - - self.freEdit = QLineEdit(self) - self.freEdit.setObjectName("setEdit") - - self.gridLayout.addWidget(self.freEdit, 7, 0, 1, 3) - - self.portEdit = QLineEdit(self) - self.portEdit.setObjectName("setEdit") - - self.gridLayout.addWidget(self.portEdit, 4, 0, 1, 3) - - self.label_2 = QLabel(self) + # 端口号 + self.label_2 = QLabel('端口号') self.label_2.setObjectName("setlabel") - self.label_2.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignVCenter) - - self.gridLayout.addWidget(self.label_2, 3, 0, 1, 1) + self.portEdit = QLineEdit() + self.portEdit.setObjectName("setEdit") + main_layout.addWidget(self.label_2) + main_layout.addWidget(self.portEdit) - self.label_3 = QLabel(self) + # 通讯频率 + self.label_3 = QLabel('通讯频率') self.label_3.setObjectName("setlabel") - self.label_3.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignVCenter) - - self.gridLayout.addWidget(self.label_3, 6, 0, 1, 1) - - self.horizontalSpacer_5 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) - - self.gridLayout.addItem(self.horizontalSpacer_5, 8, 0, 1, 4) + self.freEdit = QLineEdit() + self.freEdit.setObjectName("setEdit") + main_layout.addWidget(self.label_3) + main_layout.addWidget(self.freEdit) + # 起始值 + self.label_4 = QLabel('起始值') + self.label_4.setObjectName('setlabel') self.offsetBox = CustomBox() self.offsetBox.addItem("1") self.offsetBox.addItem("0") self.offsetBox.setObjectName("setBox") + main_layout.addWidget(self.label_4) + main_layout.addWidget(self.offsetBox) - #self.gridLayout.addWidget(QLabel('起始值'), 6, 0, 1, 1) - self.label_4 = QLabel('起始值') - self.label_4.setObjectName('setlabel') - self.gridLayout.addWidget(self.label_4,9, 0, 1, 2) - - - self.gridLayout.addWidget(self.offsetBox, 10, 0, 1, 3) - self.gridLayout.addItem(QSpacerItem(40, 20), 11, 0, 1, 4) - - - self.gridLayout_2.addLayout(self.gridLayout, 3, 5, 2, 2) - - self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) - - self.gridLayout_2.addItem(self.horizontalSpacer, 7, 0, 3, 5) - - self.verticalSpacer_2 = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) - - self.gridLayout_2.addItem(self.verticalSpacer_2, 7, 0, 3, 5) - - self.saveButton = QPushButton(self) - self.saveButton.setObjectName("setButton") - - - #self.gridLayout.addWidget(QSplitter(), 11, 0, 1, 5) - - self.gridLayout.addWidget(self.saveButton, 12, 0, 1, 3) - - self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) - - self.gridLayout_2.addItem(self.horizontalSpacer_2, 9, 2, 3, 5) - - - self.label.setText('IP地址') - self.label_2.setText(QCoreApplication.translate("self", u"\u7aef\u53e3\u53f7", None)) - self.label_3.setText(QCoreApplication.translate("self", u"\u901a\u8baf\u9891\u7387", None)) - self.saveButton.setText(QCoreApplication.translate("self", u"\u4fdd\u5b58", None)) - self.saveButton.clicked.connect(self.saveSetting) - - def setupUI(self): - # host = CharField() - # port = IntegerField() - # frequency = CharField() + # 保存按钮 + self.saveButton = QPushButton('保存') if self.tcpType == 'master': - query = TCPSetting.get_by_id(1) + self.saveButton.setObjectName("tcpSaveButton") else: - query = TCPSetting.get_by_id(2) - port = str(query.port) - host = str(query.host) - frequency = str(query.frequency) - offset = str(query.offset) - - self.ipEdit.setText(host) - self.portEdit.setText(port) - self.freEdit.setText(frequency) - self.offsetBox.setCurrentText(offset) + self.saveButton.setObjectName("setButton") + self.saveButton.clicked.connect(self.saveSetting) + main_layout.addWidget(self.saveButton) + + # 添加弹性空间 + main_layout.addStretch() + + def loadSettings(self): + """加载设置数据""" + try: + if self.tcpType == 'master': + query = TCPSetting.get_by_id(1) + else: + query = TCPSetting.get_by_id(2) + + port = str(query.port) + host = str(query.host) + frequency = str(query.frequency) + offset = str(query.offset) + + self.ipEdit.setText(host) + self.portEdit.setText(port) + self.freEdit.setText(frequency) + self.offsetBox.setCurrentText(offset) + except Exception as e: + print(f"加载TCP设置失败: {e}") + # 设置默认值 + self.ipEdit.setText("127.0.0.1") + self.portEdit.setText("502") + self.freEdit.setText("1") + self.offsetBox.setCurrentText("1") def saveSetting(self): - host = self.ipEdit.text() - port = self.portEdit.text() - frequency = self.freEdit.text() - offset = self.offsetBox.currentText() - if self.tcpType == 'master': - TCPSetting.update(host = host, port = port, frequency = frequency, offset = offset).where(TCPSetting.tcpType == 'master').execute() - else: - TCPSetting.update(host = host, port = port, frequency = frequency, offset = offset).where(TCPSetting.tcpType == 'slave').execute() - QMessageBox.information(self, 'Sucess', '保存成功') \ No newline at end of file + """保存设置""" + try: + host = self.ipEdit.text() + port = self.portEdit.text() + frequency = self.freEdit.text() + offset = self.offsetBox.currentText() + + if self.tcpType == 'master': + TCPSetting.update(host=host, port=port, frequency=frequency, offset=offset).where(TCPSetting.tcpType == 'master').execute() + else: + TCPSetting.update(host=host, port=port, frequency=frequency, offset=offset).where(TCPSetting.tcpType == 'slave').execute() + + # 创建消息框 + QMessageBox.information(self, '保存成功', f'TCP{self.tcpType}站配置已保存!') + + except Exception as e: + QMessageBox.critical(self, '保存失败', f'保存TCP设置时发生错误:{str(e)}') \ No newline at end of file diff --git a/UI/TrendManage/TrendWidget.py b/UI/TrendManage/TrendWidget.py index faee129..504cb78 100644 --- a/UI/TrendManage/TrendWidget.py +++ b/UI/TrendManage/TrendWidget.py @@ -141,7 +141,7 @@ class TrendWidgets(QWidget): self.queryBtn = QToolButton() self.queryBtn.setObjectName("trendQueryBtn") self.queryBtn.setText("查询数据") - self.queryBtn.setIcon(qtawesome.icon('fa.search', color='#FFFFFF')) + self.queryBtn.setIcon(qtawesome.icon('fa.search', color='#2277EF')) self.queryBtn.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.queryBtn.setIconSize(QSize(16, 16)) self.queryBtn.setToolTip("按时间范围查询变量数据") @@ -151,7 +151,7 @@ class TrendWidgets(QWidget): self.refreshBtn = QToolButton() self.refreshBtn.setObjectName("trendRefreshBtn") self.refreshBtn.setText("刷新列表") - self.refreshBtn.setIcon(qtawesome.icon('fa.refresh', color='#FFFFFF')) + self.refreshBtn.setIcon(qtawesome.icon('fa.refresh', color='#059669')) self.refreshBtn.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.refreshBtn.setIconSize(QSize(16, 16)) self.refreshBtn.setToolTip("刷新变量列表") @@ -167,7 +167,7 @@ class TrendWidgets(QWidget): self.addToTrendBtn = QToolButton() self.addToTrendBtn.setObjectName("trendAddBtn") self.addToTrendBtn.setText("添加变量") - self.addToTrendBtn.setIcon(qtawesome.icon('fa.plus', color='#FFFFFF')) + self.addToTrendBtn.setIcon(qtawesome.icon('fa.plus', color='#7C3AED')) self.addToTrendBtn.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.addToTrendBtn.setIconSize(QSize(16, 16)) self.addToTrendBtn.setToolTip("将选中的变量添加到趋势图") @@ -177,7 +177,7 @@ class TrendWidgets(QWidget): self.clearAllBtn = QToolButton() self.clearAllBtn.setObjectName("trendClearBtn") self.clearAllBtn.setText("清除所有") - self.clearAllBtn.setIcon(qtawesome.icon('fa.trash', color='#FFFFFF')) + self.clearAllBtn.setIcon(qtawesome.icon('fa.trash', color='#DC2626')) self.clearAllBtn.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.clearAllBtn.setIconSize(QSize(16, 16)) self.clearAllBtn.setToolTip("清除趋势图中的所有变量") diff --git a/UI/UserManage/UserTable.py b/UI/UserManage/UserTable.py index d8fc10a..4bd2c4b 100644 --- a/UI/UserManage/UserTable.py +++ b/UI/UserManage/UserTable.py @@ -29,7 +29,7 @@ class UserTableView(QTableView): self.setSelectionBehavior(QAbstractItemView.SelectRows) - self.model = UserTableModel([' ID', '用户名', '登陆密码', '备注', '创建时间', '工程管理权限', '通讯配置权限', '用户管理权限','趋势查看权限','操作'],[], table = self) + self.model = UserTableModel([' ID', '用户名', '登陆密码', '备注', '创建时间', '工程管理权限', '通讯配置权限', '用户管理权限','趋势查看权限','操作'],[], table = self) self.setModel(self.model) self.header = CheckBoxHeader(changeY = True) self.header.setObjectName('userHeader') diff --git a/UI/UserManage/UserWidget.py b/UI/UserManage/UserWidget.py index fdf957c..120919a 100644 --- a/UI/UserManage/UserWidget.py +++ b/UI/UserManage/UserWidget.py @@ -3,6 +3,7 @@ from PyQt5.QtCore import QSize, Qt from PyQt5.Qt import * from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import QSplitter +import qtawesome as qta from .UserTable import UserTableView from utils.DBModels.UserModels import User @@ -15,20 +16,112 @@ class UserWidgets(QtWidgets.QWidget): def __init__(self, parent=None): super(UserWidgets, self).__init__(parent) self.setAttribute(Qt.WA_StyledBackground, True) + self.setupUI() + + def setupButtonIcon(self, button, icon_name, color): + """设置按钮图标,支持不同状态的颜色变化""" + # 正常状态图标 + normal_icon = qta.icon(icon_name, color=color) - self.createBtn = QPushButton(QIcon('./Static/add.png'), '添加用户') - self.createBtn.setObjectName('forceBtn') - self.createBtn.setIconSize(QSize(22, 22)) + # 悬停状态图标(稍微亮一些) + hover_color = self.lightenColor(color, 0.2) + hover_icon = qta.icon(icon_name, color=hover_color) + + # 按下状态图标(稍微暗一些) + pressed_color = self.darkenColor(color, 0.2) + pressed_icon = qta.icon(icon_name, color=pressed_color) + + # 设置图标 + button.setIcon(normal_icon) + + # 存储不同状态的图标,用于状态切换 + button._normal_icon = normal_icon + button._hover_icon = hover_icon + button._pressed_icon = pressed_icon + + # 连接事件 + button.enterEvent = lambda event: self.onButtonEnter(button, event) + button.leaveEvent = lambda event: self.onButtonLeave(button, event) + button.mousePressEvent = lambda event: self.onButtonPress(button, event) + button.mouseReleaseEvent = lambda event: self.onButtonRelease(button, event) + + def lightenColor(self, color, factor): + """使颜色变亮""" + if color.startswith('#'): + # 十六进制颜色 + r = int(color[1:3], 16) + g = int(color[3:5], 16) + b = int(color[5:7], 16) + + r = min(255, int(r + (255 - r) * factor)) + g = min(255, int(g + (255 - g) * factor)) + b = min(255, int(b + (255 - b) * factor)) + + return f"#{r:02x}{g:02x}{b:02x}" + return color + + def darkenColor(self, color, factor): + """使颜色变暗""" + if color.startswith('#'): + # 十六进制颜色 + r = int(color[1:3], 16) + g = int(color[3:5], 16) + b = int(color[5:7], 16) + + r = max(0, int(r * (1 - factor))) + g = max(0, int(g * (1 - factor))) + b = max(0, int(b * (1 - factor))) + + return f"#{r:02x}{g:02x}{b:02x}" + return color + + def onButtonEnter(self, button, event): + """按钮鼠标进入事件""" + if hasattr(button, '_hover_icon'): + button.setIcon(button._hover_icon) + # 调用原始的enterEvent + QPushButton.enterEvent(button, event) + + def onButtonLeave(self, button, event): + """按钮鼠标离开事件""" + if hasattr(button, '_normal_icon'): + button.setIcon(button._normal_icon) + # 调用原始的leaveEvent + QPushButton.leaveEvent(button, event) + + def onButtonPress(self, button, event): + """按钮鼠标按下事件""" + if hasattr(button, '_pressed_icon'): + button.setIcon(button._pressed_icon) + # 调用原始的mousePressEvent + QPushButton.mousePressEvent(button, event) + + def onButtonRelease(self, button, event): + """按钮鼠标释放事件""" + # 检查鼠标是否还在按钮上 + if button.rect().contains(event.pos()): + if hasattr(button, '_hover_icon'): + button.setIcon(button._hover_icon) + else: + if hasattr(button, '_normal_icon'): + button.setIcon(button._normal_icon) + # 调用原始的mouseReleaseEvent + QPushButton.mouseReleaseEvent(button, event) + + def setupUI(self): + # 添加用户按钮 + self.createBtn = QPushButton('添加用户') + self.createBtn.setObjectName('createBtn') + self.createBtn.setIconSize(QSize(18, 18)) self.createBtn.clicked.connect(self.createUser) + self.setupButtonIcon(self.createBtn, 'fa5s.user-plus', '#2277EF') - # self.importBtn = QPushButton(QIcon('./Static/import.png'), '导入变量') - # self.importBtn.setObjectName('importBtn') - # self.importBtn.setIconSize(QSize(22, 22)) - - self.delBtn = QPushButton(QIcon('./Static/delete.png'), '批量删除') + # 批量删除按钮 + self.delBtn = QPushButton('批量删除') self.delBtn.setObjectName('delBtn') - self.delBtn.setIconSize(QSize(22, 22)) + self.delBtn.setIconSize(QSize(18, 18)) self.delBtn.clicked.connect(self.deleteUser) + self.setupButtonIcon(self.delBtn, 'fa5s.user-minus', '#DC2626') self.userView = UserTableView() self.userView.setObjectName('userView') diff --git a/UI/VarManages/ModbusModel.py b/UI/VarManages/ModbusModel.py index 8ac332f..62d5dd2 100644 --- a/UI/VarManages/ModbusModel.py +++ b/UI/VarManages/ModbusModel.py @@ -296,7 +296,7 @@ class ModbusButtonDelegate(BaseButtonDelegate): widget = QWidget() widget.setLayout(hboxLayout) - + widget.setStyleSheet("QComboBox { background-color: transparent; }") # 所有下拉框使用统一样式 widget.setObjectName('ModbusButtonWidget') comboBox.setObjectName('ModbusOrderBox') @@ -530,7 +530,7 @@ class ModbusTypeBox(QItemDelegate): comboBox.setProperty('disabled', False) widget = QWidget() - # widget.setStyleSheet("QWidget { background-color: transparent; }") + widget.setStyleSheet("QComboBox { background-color: transparent; }") widget.setLayout(hboxLayout) self.parent().setIndexWidget(index, widget) self.parent().openPersistentEditor(index) @@ -565,7 +565,7 @@ class ModbusVarModelBox(QItemDelegate): setattr(self, comBox, QComboBox()) comboBox = getattr(self, comBox) comboBox = QComboBox(self.parent()) - items = ['本地值', '模拟值', '远程值'] + items = ['本地值', '模拟值'] comboBox.addItems(items) comboBox.setCurrentText(str(self.parent().model.datas[index.row()][index.column()])) @@ -579,7 +579,7 @@ class ModbusVarModelBox(QItemDelegate): hboxLayout.setContentsMargins(2, 2, 2, 2) comboBox.index = [index.row(), index.column()] widget = QWidget() - # widget.setStyleSheet("QWidget { background-color: transparent; }") + widget.setStyleSheet("QComboBox { background-color: transparent; }") widget.setLayout(hboxLayout) self.parent().setIndexWidget(index, widget) self.parent().openPersistentEditor(index) diff --git a/UI/VarManages/TCRTDModel.py b/UI/VarManages/TCRTDModel.py index 7fa0927..7d443a0 100644 --- a/UI/VarManages/TCRTDModel.py +++ b/UI/VarManages/TCRTDModel.py @@ -66,8 +66,6 @@ class TcRtdModel(VarTableModel): print("行或者列有问题") return QVariant() if role == Qt.BackgroundRole: - if QModelIndex.row() % 2 == 0 and self.datas[QModelIndex.row()][3] not in Globals.getValue('forceVars'): - return QtGui.QColor('#EFEFEF') if self.datas[QModelIndex.row()][3] in Globals.getValue('forceVars'): return QtGui.QColor('#00FF7F') if role == Qt.TextColorRole: @@ -188,21 +186,6 @@ class TcRtdButtonDelegate(BaseButtonDelegate): QWidget { background-color: transparent; } - QPushButton { - background-color: rgba(255, 255, 255, 180); - border: 1px solid #E5E7EB; - border-radius: 3px; - padding: 3px; - margin: 1px; - min-height: 20px; - max-height: 24px; - min-width: 24px; - max-width: 28px; - } - QPushButton:hover { - background-color: rgba(255, 255, 255, 255); - border-color: #2277EF; - } """) self.parent().setIndexWidget( @@ -350,6 +333,14 @@ class TcRtdTypeDelegate(TcRtdButtonDelegate): super(TcRtdTypeDelegate, self).__init__(parent) def paint(self, painter, option, index): + if index.data(Qt.BackgroundRole): + height = option.rect.height() + top = option.rect.top() + # 减少高度调整,保持更多的绘制区域 + paint_rect = option.rect + paint_rect.setHeight(max(46, height - 4)) # 最小保持46px高度 + paint_rect.moveTop(top + 2) + painter.fillRect(paint_rect, index.data(Qt.BackgroundRole)) if not self.parent().indexWidget(index): comboBox = QComboBox(self.parent()) if index.row() < 8: @@ -376,6 +367,7 @@ class TcRtdTypeDelegate(TcRtdButtonDelegate): # comboBox.setStyleSheet("QComboBox { background-color: #EFEFEF }") # else: # comboBox.setStyleSheet("QComboBox { background-color: #e9e7e3 }") + widget.setStyleSheet("QComboBox { background-color: transparent; }") self.parent().setIndexWidget( index, widget diff --git a/UI/VarManages/VarTable.py b/UI/VarManages/VarTable.py index deed53e..24eebcd 100644 --- a/UI/VarManages/VarTable.py +++ b/UI/VarManages/VarTable.py @@ -102,7 +102,8 @@ class VarTableView(QTableView): self.setupUi() def setHeader(self): - + self.delegate = BackgroundDelegate(self) + self.setItemDelegate(self.delegate) self.setItemDelegateForColumn(11, ModbusButtonDelegate(self)) self.setItemDelegateForColumn(5, ModbusTypeBox(self)) self.setItemDelegateForColumn(10, ModbusVarModelBox(self)) diff --git a/UI/VarManages/VarWidget.py b/UI/VarManages/VarWidget.py index 058ce13..7537365 100644 --- a/UI/VarManages/VarWidget.py +++ b/UI/VarManages/VarWidget.py @@ -2,6 +2,7 @@ from PyQt5 import QtCore, QtWidgets from PyQt5.QtCore import QSize, Qt, QTimer from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import QSplitter, QPushButton, QFileDialog, QMessageBox, QVBoxLayout +import qtawesome as qta from UI.VarManages.VarTable import VarTableView, HartTableView, TcRtdTableView, AnalogTableView, \ HartSimulateTableView, RpcVarTableView @@ -21,44 +22,134 @@ class VarWidgets(QtWidgets.QWidget): super(VarWidgets, self).__init__(parent) self.modbusType = modbusType self.setupUI() + + def setupButtonIcon(self, button, icon_name, color): + """设置按钮图标,支持不同状态的颜色变化""" + # 正常状态图标 + normal_icon = qta.icon(icon_name, color=color) + + # 悬停状态图标(稍微亮一些) + hover_color = self.lightenColor(color, 0.2) + hover_icon = qta.icon(icon_name, color=hover_color) + + # 按下状态图标(稍微暗一些) + pressed_color = self.darkenColor(color, 0.2) + pressed_icon = qta.icon(icon_name, color=pressed_color) + + # 设置图标 + button.setIcon(normal_icon) + + # 存储不同状态的图标,用于状态切换 + button._normal_icon = normal_icon + button._hover_icon = hover_icon + button._pressed_icon = pressed_icon + + # 连接事件 + button.enterEvent = lambda event: self.onButtonEnter(button, event) + button.leaveEvent = lambda event: self.onButtonLeave(button, event) + button.mousePressEvent = lambda event: self.onButtonPress(button, event) + button.mouseReleaseEvent = lambda event: self.onButtonRelease(button, event) + + def lightenColor(self, color, factor): + """使颜色变亮""" + if color.startswith('#'): + # 十六进制颜色 + r = int(color[1:3], 16) + g = int(color[3:5], 16) + b = int(color[5:7], 16) + + r = min(255, int(r + (255 - r) * factor)) + g = min(255, int(g + (255 - g) * factor)) + b = min(255, int(b + (255 - b) * factor)) + + return f"#{r:02x}{g:02x}{b:02x}" + return color + + def darkenColor(self, color, factor): + """使颜色变暗""" + if color.startswith('#'): + # 十六进制颜色 + r = int(color[1:3], 16) + g = int(color[3:5], 16) + b = int(color[5:7], 16) + + r = max(0, int(r * (1 - factor))) + g = max(0, int(g * (1 - factor))) + b = max(0, int(b * (1 - factor))) + + return f"#{r:02x}{g:02x}{b:02x}" + return color + + def onButtonEnter(self, button, event): + """按钮鼠标进入事件""" + if hasattr(button, '_hover_icon'): + button.setIcon(button._hover_icon) + # 调用原始的enterEvent + QPushButton.enterEvent(button, event) + + def onButtonLeave(self, button, event): + """按钮鼠标离开事件""" + if hasattr(button, '_normal_icon'): + button.setIcon(button._normal_icon) + # 调用原始的leaveEvent + QPushButton.leaveEvent(button, event) + + def onButtonPress(self, button, event): + """按钮鼠标按下事件""" + if hasattr(button, '_pressed_icon'): + button.setIcon(button._pressed_icon) + # 调用原始的mousePressEvent + QPushButton.mousePressEvent(button, event) + + def onButtonRelease(self, button, event): + """按钮鼠标释放事件""" + # 检查鼠标是否还在按钮上 + if button.rect().contains(event.pos()): + if hasattr(button, '_hover_icon'): + button.setIcon(button._hover_icon) + else: + if hasattr(button, '_normal_icon'): + button.setIcon(button._normal_icon) + # 调用原始的mouseReleaseEvent + QPushButton.mouseReleaseEvent(button, event) def setupUI(self): self.setAttribute(Qt.WA_StyledBackground, True) - self.createBtn = QPushButton(QIcon('./Static/add.png'), '新建变量') + # 新建变量按钮 + self.createBtn = QPushButton('新建变量') self.createBtn.setObjectName('createBtn') - self.createBtn.setIconSize(QSize(22, 22)) + self.createBtn.setIconSize(QSize(18, 18)) self.createBtn.clicked.connect(self.createVar) + self.setupButtonIcon(self.createBtn, 'fa5s.plus', '#2277EF') - self.forceBtn = QPushButton(QIcon('./Static/start.png'), '批量强制') + # 批量强制按钮 + self.forceBtn = QPushButton('批量强制') self.forceBtn.setObjectName('forceBtn') - self.forceBtn.setIconSize(QSize(22, 22)) + self.forceBtn.setIconSize(QSize(18, 18)) self.forceBtn.clicked.connect(self.forceVar) + self.setupButtonIcon(self.forceBtn, 'fa5s.play', '#F59E0B') - self.clearBtn = QPushButton(QIcon('./Static/clear.png'), '清除颜色') + # 清除颜色按钮 + self.clearBtn = QPushButton('清除颜色') self.clearBtn.setObjectName('clearBtn') - self.clearBtn.setIconSize(QSize(22, 22)) + self.clearBtn.setIconSize(QSize(18, 18)) self.clearBtn.clicked.connect(self.clearColour) + self.setupButtonIcon(self.clearBtn, 'fa5s.eraser', '#DC2626') - # self.importBtn = QPushButton(QIcon(':/Static/import.png'), '导入变量') - # self.importBtn.setObjectName('importBtn') - # self.importBtn.setIconSize(QSize(22, 22)) - # self.importBtn.clicked.connect(self.importVar) - - # self.exportBtn = QPushButton(QIcon(':/Static/export.png'), '导出变量') - # self.exportBtn.setObjectName('exportBtn') - # self.exportBtn.setIconSize(QSize(22, 22)) - # self.exportBtn.clicked.connect(self.exportVar) - - self.messageBtn = QPushButton(QIcon('./Static/message.png'), '查看报文') + # 查看报文按钮 + self.messageBtn = QPushButton('查看报文') self.messageBtn.setObjectName('messageBtn') - self.messageBtn.setIconSize(QSize(22, 22)) + self.messageBtn.setIconSize(QSize(18, 18)) self.messageBtn.clicked.connect(self.showMessage) + self.setupButtonIcon(self.messageBtn, 'fa5s.envelope', '#8B5CF6') - self.startProtocolBtn = QPushButton(QIcon('./Static/startProtocol.png'), '开始通讯') + # 开始通讯按钮 + self.startProtocolBtn = QPushButton('开始通讯') self.startProtocolBtn.setObjectName('startProtocolBtn') - self.startProtocolBtn.setIconSize(QSize(22, 22)) + self.startProtocolBtn.setIconSize(QSize(18, 18)) self.startProtocolBtn.clicked.connect(self.startProtocol) + self.setupButtonIcon(self.startProtocolBtn, 'fa5s.play-circle', '#059669') self.varView = VarTableView(self.modbusType, self) self.varView.setObjectName('varView') @@ -91,7 +182,6 @@ class VarWidgets(QtWidgets.QWidget): # self.comboBox.currentIndexChanged.connect(self.on_comboBox_currentIndexChanged) - self.horizontalHeader = self.varView.horizontalHeader() self.horizontalHeader.sectionClicked.connect(self.on_view_horizontalHeader_sectionClicked) @@ -308,7 +398,7 @@ class VarWidgets(QtWidgets.QWidget): if success: self._isPopenOpen = True self.startProtocolBtn.setText('停止通讯') - self.startProtocolBtn.setIcon(QIcon('./Static/pause.png')) + self.setupButtonIcon(self.startProtocolBtn, 'fa5s.stop-circle', '#DC2626') else: QMessageBox.warning(self, '错误', 'Modbus 通讯启动失败', QMessageBox.Yes) except Exception as e: @@ -329,7 +419,7 @@ class VarWidgets(QtWidgets.QWidget): if success: self._isPopenOpen = False self.startProtocolBtn.setText('开始通讯') - self.startProtocolBtn.setIcon(QIcon('./Static/startProtocol.png')) + self.setupButtonIcon(self.startProtocolBtn, 'fa5s.play-circle', '#059669') else: QMessageBox.warning(self, '错误', 'Modbus 通讯停止失败', QMessageBox.Yes) except Exception as e: @@ -338,7 +428,7 @@ class VarWidgets(QtWidgets.QWidget): def initIcon(self): self._isPopenOpen = False self.startProtocolBtn.setText('开始通讯') - self.startProtocolBtn.setIcon(QIcon('./Static/startProtocol.png')) + self.setupButtonIcon(self.startProtocolBtn, 'fa5s.play-circle', '#059669') def performSearch(self, searchText): """统一搜索接口""" @@ -400,21 +490,19 @@ class TcRtdWidgets(VarWidgets): def setupUI(self): self.setAttribute(Qt.WA_StyledBackground, True) - self.forceBtn = QPushButton(QIcon('./Static/start.png'), '批量强制') + # 批量强制按钮 + self.forceBtn = QPushButton('批量强制') self.forceBtn.setObjectName('forceBtn') - self.forceBtn.setIconSize(QSize(22, 22)) + self.forceBtn.setIconSize(QSize(18, 18)) self.forceBtn.clicked.connect(self.forceVar) + self.setupButtonIcon(self.forceBtn, 'fa5s.play', '#F59E0B') - - # self.startProtocolBtn = QPushButton(QIcon('./Static/startProtocol.png'), '开始通讯') - # self.startProtocolBtn.setObjectName('startProtocolBtn') - # self.startProtocolBtn.setIconSize(QSize(22, 22)) - # self.startProtocolBtn.clicked.connect(self.startProtocol) - - self.clearBtn = QPushButton(QIcon('./Static/clear.png'), '清除颜色') + # 清除颜色按钮 + self.clearBtn = QPushButton('清除颜色') self.clearBtn.setObjectName('clearBtn') - self.clearBtn.setIconSize(QSize(22, 22)) + self.clearBtn.setIconSize(QSize(18, 18)) self.clearBtn.clicked.connect(self.clearColour) + self.setupButtonIcon(self.clearBtn, 'fa5s.eraser', '#DC2626') self.varView = TcRtdTableView() self.varView.setObjectName('varView') @@ -494,20 +582,19 @@ class AnalogWidgets(VarWidgets): self.setAttribute(Qt.WA_StyledBackground, True) - self.forceBtn = QPushButton(QIcon('./Static/start.png'), '批量强制') + # 批量强制按钮 + self.forceBtn = QPushButton('批量强制') self.forceBtn.setObjectName('forceBtn') - self.forceBtn.setIconSize(QSize(22, 22)) + self.forceBtn.setIconSize(QSize(18, 18)) self.forceBtn.clicked.connect(self.forceVar) + self.setupButtonIcon(self.forceBtn, 'fa5s.play', '#F59E0B') - self.startProtocolBtn = QPushButton(QIcon('./Static/startProtocol.png'), '开始通讯') - # # self.startProtocolBtn.setObjectName('startProtocolBtn') - # self.startProtocolBtn.setIconSize(QSize(22, 22)) - # self.startProtocolBtn.clicked.connect(self.startProtocol) - - self.clearBtn = QPushButton(QIcon('./Static/clear.png'), '清除颜色') + # 清除颜色按钮 + self.clearBtn = QPushButton('清除颜色') self.clearBtn.setObjectName('clearBtn') - self.clearBtn.setIconSize(QSize(22, 22)) + self.clearBtn.setIconSize(QSize(18, 18)) self.clearBtn.clicked.connect(self.clearColour) + self.setupButtonIcon(self.clearBtn, 'fa5s.eraser', '#DC2626') self.varView = AnalogTableView() self.varView.setObjectName('varView') diff --git a/bin.py b/bin.py index 9b010ff..eafcec1 100644 --- a/bin.py +++ b/bin.py @@ -18,7 +18,10 @@ if __name__ == '__main__': app.setStyle(QStyleFactory.create('Fusion')) app.setStyleSheet(CommonHelper.readQss('Static/Main.qss') + CommonHelper.readQss('Static/profibus.qss') - + CommonHelper.readQss('Static/Area.qss')) + + CommonHelper.readQss('Static/Area.qss') + + CommonHelper.readQss('Static/CommSettings.qss') + + CommonHelper.readQss('Static/TrendSettings.qss') + + CommonHelper.readQss('Static/VarTableSettings.qss')) reg = Register() if not reg.checkLicense(): regWidget = RegisterWidget()