diff --git a/Static/Main.qss b/Static/Main.qss index fda4bf6..cef233e 100644 --- a/Static/Main.qss +++ b/Static/Main.qss @@ -4,6 +4,39 @@ QComboBox#dataTypeCombox, QComboBox#orderCombox{ } +QComboBox#tbcombox{ + + background-color: #f0f0f0; + + border: none; + + padding-left: 5px; + + border-radius: 5px; + + margin-left: -10px; + +} + +QComboBox#tbcombox::drop-down{ + + image: url(Static/down.png); + + subcontrol-origin: padding; + + subcontrol-position: top right; + + background-color: #f0f0f0; + + width: 15px; + + border:none; + + border-radius: 5px; + +} + + QTabBar::close-button { @@ -462,4 +495,14 @@ QProgressBar { color: black; - } \ No newline at end of file + } + +QWidget#tbwidget{ + + background-color: #ffffff; + + padding: 0px; + + margin: 0px; + +} diff --git a/Static/PA块信息表.xlsx b/Static/PA块信息表.xlsx index 942cfd1..7f944c1 100644 Binary files a/Static/PA块信息表.xlsx and b/Static/PA块信息表.xlsx differ diff --git a/Static/down.png b/Static/down.png new file mode 100644 index 0000000..f0e4f6b Binary files /dev/null and b/Static/down.png differ diff --git a/UI/BlockParameterManageWidget.py b/UI/BlockParameterManageWidget.py index 86f9510..a7c8ca5 100644 --- a/UI/BlockParameterManageWidget.py +++ b/UI/BlockParameterManageWidget.py @@ -1,7 +1,8 @@ +from tkinter.ttk import Combobox import qtawesome - -from PyQt5.QtWidgets import QPushButton,QStackedWidget, QLineEdit, QVBoxLayout, QHBoxLayout, QWidget, QLabel, QSplitter, QButtonGroup +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import QStyledItemDelegate, QStyle, QComboBox, QMessageBox, QPushButton,QStackedWidget, QLineEdit, QVBoxLayout, QHBoxLayout, QWidget, QLabel, QSplitter, QButtonGroup from utils.DBModels.DeviceParModels import * from UI.BlockParameterView import ParmView from UI.SearchAddressWidget import SearchAddressWidget @@ -9,9 +10,134 @@ from UI.SearchAddressWidget import SearchAddressWidget from utils.DBModels.DeviceParModels import * from UI.LoadingDataWidget import LoadingDataWidget +class HideTextDelegate(QStyledItemDelegate): + def paint(self, painter, option, index): + # 仅在下拉列表中绘制文本,避免在ComboBox显示区域绘制 + if option.state & QStyle.State_Enabled: + super().paint(painter, option, index) + + def sizeHint(self, option, index): + # 返回原始大小,确保下拉列表项不受ComboBox宽度影响 + return super().sizeHint(option, index) + +class TbCombox(QComboBox): + def __init__(self): + super().__init__() + self.initUI() + + def initUI(self): + # 创建ComboBox + + self.addItems(["选项很长很长很长", "选项2", "选项3"]) + self.setEditable(True) # 设置为可编辑以应用样式表隐藏文本 + self.setObjectName('tbcombox') + # 设置样式隐藏文本 + self.lineEdit().setStyleSheet("color: transparent; border:none; background-color: #f0f0f0") + self.lineEdit().setCursor(Qt.ArrowCursor) + self.lineEdit().setReadOnly(True) + + # 设置自定义代理以调整下拉列表行为 + self.delegate = HideTextDelegate(self) + self.setItemDelegate(self.delegate) + + # 设置ComboBox的固定大小 + self.setFixedSize(30, 40) + + # 确保下拉列表宽度适应最长项 + max_width = max(self.fontMetrics().width(self.itemText(i)) for i in range(self.count())) + self.view().setMinimumWidth(max_width) + + + +class DynamicAddBlock(QHBoxLayout): + def __init__(self, blocklist): + super().__init__() + self.blocklist = blocklist + self.buttonlist = [] + self.blockViewlist = [] + self.initUI() + + def initUI(self): + pbNumber = self.blocklist[0] + tbNumber = self.blocklist[1] + fbNumber = self.blocklist[2] + + for i in range(pbNumber): + pblockBtn = QPushButton('物理块') + + pblockBtn.setCheckable(True) + pblockBtn.setFixedSize(90, 43) + pblockBtn.setObjectName("parameBtn") + pblockBtn.setIcon(qtawesome.icon('fa.th-large', color='#1fbb6f')) + # pblockBtn.setCheckable(True) + pblockBtn.clicked.connect(lambda _, pbbtn = pblockBtn: self.switchParameterWidget(pbbtn)) + self.addWidget(pblockBtn) + self.buttonlist.append(pblockBtn) + physicalBlockView = ParmView(PhysicalBlock) + self.blockViewlist.append(physicalBlockView) + if i == 0: + pblockBtn.setChecked(True) + + + + for i in range(fbNumber): + fblockBtn = QPushButton('功能块' + str(i + 1)) + fblockBtn.setFixedSize(90, 43) + fblockBtn.setCheckable(True) + fblockBtn.setObjectName("parameBtn") + fblockBtn.setIcon(qtawesome.icon('fa.th-large', color='#1fbb6f')) + fblockBtn.clicked.connect(lambda _, fbbtn = fblockBtn: self.switchParameterWidget(fbbtn)) + self.addWidget(fblockBtn) + self.buttonlist.append(fblockBtn) + aiFunctionBlockView = ParmView(AIFunctionBlock) + self.blockViewlist.append(aiFunctionBlockView) + + for i in range(tbNumber): + tbwidget = QWidget() + tbwidget.setObjectName('tbwidget') + tblayout = QHBoxLayout() + + tbwidget.setLayout(tblayout) + tbcombox = TbCombox() + + tblockBtn = QPushButton('转换块' + str(i + 1)) + tblockBtn.setObjectName("parameBtn") + tblockBtn.setFixedSize(90, 43) + tblockBtn.setCheckable(True) + tblockBtn.setIcon(qtawesome.icon('fa.th-large', color='#1fbb6f')) + tblockBtn.clicked.connect(lambda _, tbbtn = tblockBtn: self.switchParameterWidget(tbbtn)) + tbcombox.currentIndexChanged.connect(lambda index, combox = tbcombox, tbbtn = tblockBtn : self.chooseTbtype(index, combox, tbbtn)) + + tblayout.addWidget(tblockBtn) + tblayout.addWidget(tbcombox) + self.addWidget(tbwidget) + self.buttonlist.append(tblockBtn) + pressureTBlockView = ParmView(PressureTranslationBlock) + self.blockViewlist.append(pressureTBlockView) + + self.parameterButtonGroup = QButtonGroup() + self.parameterButtonGroup.setExclusive(True) + for button in self.buttonlist: + self.parameterButtonGroup.addButton(button) + + self.parameStackWidget = QStackedWidget() + for view in self.blockViewlist: + self.parameStackWidget.addWidget(view) + + + def switchParameterWidget(self, buttonType): + print(buttonType) + for index , button in enumerate(self.buttonlist): + if button == buttonType: + self.parameStackWidget.setCurrentIndex(index) + + def chooseTbtype(self, index, combox, button): + tbType = combox.itemText(index) + button.setText(tbType) + class BlockParameterManageWidget(QWidget): def __init__(self): @@ -20,12 +146,12 @@ class BlockParameterManageWidget(QWidget): def initUI(self): - self.pressureTBlockView = ParmView(PressureTranslationBlock) - self.aiFunctionBlockView = ParmView(AIFunctionBlock) - self.physicalBlockView = ParmView(PhysicalBlock) + + blocklist = [1,2,2] + self.blockLayout = DynamicAddBlock(blocklist) self.mainlayout = QVBoxLayout() - self.parameStackWidget = QStackedWidget() + self.settingLayout = QHBoxLayout() self.deviceAddressLabel = QLabel('从站地址') self.deviceAddressLabel.setObjectName('deviceAddressLabel') @@ -42,55 +168,19 @@ class BlockParameterManageWidget(QWidget): self.deviceAddressSearchBtn.clicked.connect(self.searchAddress) self.deviceAddressSearchBtn.setObjectName("parameBtn") - self.pblockBtn = QPushButton('物理块') - self.pblockBtn.setCheckable(True) - self.pblockBtn.setChecked(True) - self.pblockBtn.setObjectName("parameBtn") - self.pblockBtn.setIcon(qtawesome.icon('fa.th-large', color='#1fbb6f')) - # self.pblockBtn.setCheckable(True) - self.pblockBtn.clicked.connect(lambda: self.switchParameterWidget('pblockBtn')) - - self.fblockBtn = QPushButton('功能块') - self.fblockBtn.setCheckable(True) - self.fblockBtn.setObjectName("parameBtn") - self.fblockBtn.setIcon(qtawesome.icon('fa.th-large', color='#1fbb6f')) - self.fblockBtn.clicked.connect(lambda: self.switchParameterWidget('fblockBtn')) - # self.pblockBtn.setCheckable(True) - - self.tblockBtn = QPushButton('转换块') - self.tblockBtn.setObjectName("parameBtn") - self.tblockBtn.setCheckable(True) - self.tblockBtn.setIcon(qtawesome.icon('fa.th-large', color='#1fbb6f')) - self.tblockBtn.clicked.connect(lambda: self.switchParameterWidget('tblockBtn')) - # self.tblockBtn.setCheckable(True) - - self.parameterButtonGroup = QButtonGroup() - self.parameterButtonGroup.setExclusive(True) - self.parameterButtonGroup.addButton(self.pblockBtn) - self.parameterButtonGroup.addButton(self.fblockBtn) - self.parameterButtonGroup.addButton(self.tblockBtn) - - self.settingLayout.addWidget(self.deviceAddressLabel, 1) self.settingLayout.addWidget(self.deviceAddressEdit, 1) self.settingLayout.addWidget(self.confirmBtn, 1) self.settingLayout.addWidget(self.deviceAddressSearchBtn, 1) - self.settingLayout.addWidget(self.pblockBtn, 1) - self.settingLayout.addWidget(self.fblockBtn, 1) - self.settingLayout.addWidget(self.tblockBtn, 1) - self.settingLayout.addWidget(QSplitter(), 18) + # self.settingLayout.addLayout(self.blockLayout) + + self.splitter = QSplitter() + self.settingLayout.addWidget(self.splitter, 18) - self.mainlayout.addLayout(self.settingLayout,1) - self.parameStackWidget.addWidget(self.physicalBlockView) - self.parameStackWidget.addWidget(self.aiFunctionBlockView) - self.parameStackWidget.addWidget(self.pressureTBlockView) - - - - - self.mainlayout.addWidget(self.parameStackWidget, 20) + self.widget = QWidget() + self.mainlayout.addWidget(self.widget, 20) # self.proxy = QtCore.QSortFilterProxyModel(self) # self.parameTableView.proxy = self.proxy @@ -111,22 +201,25 @@ class BlockParameterManageWidget(QWidget): self.setLayout(self.mainlayout) - def switchParameterWidget(self,blockType): - match blockType: - case "pblockBtn": - self.parameStackWidget.setCurrentIndex(0) - case "fblockBtn": - self.parameStackWidget.setCurrentIndex(1) - case "tblockBtn": - self.parameStackWidget.setCurrentIndex(2) - def refreshData(self): - - self.loadingDataWidget = LoadingDataWidget() - self.loadingDataWidget.loadData() - - model = self.parameStackWidget.currentWidget().model - model.updateColumn(5, '查询中...') + if self.deviceAddressEdit.text(): + self.splitter.deleteLater() + self.widget.deleteLater() + self.loadingDataWidget = LoadingDataWidget() + self.loadingDataWidget.loadData() + + + self.settingLayout.addLayout(self.blockLayout) + self.settingLayout.addWidget(QSplitter(), 18) + self.mainlayout.addWidget(self.blockLayout.parameStackWidget, 20) + model = self.blockLayout.parameStackWidget.currentWidget().model + model.updateColumn(5, '查询中...') + else: + reply = QMessageBox.question(self.parent(), + '警告', + "请输入从站地址", + QMessageBox.Yes) + return def searchAddress(self): self.searchAddressWidget = SearchAddressWidget(self.deviceAddressEdit) diff --git a/UI/LoadingDataWidget.py b/UI/LoadingDataWidget.py index 5f82341..65da807 100644 --- a/UI/LoadingDataWidget.py +++ b/UI/LoadingDataWidget.py @@ -8,7 +8,7 @@ class LoadDataThread(QThread): def run(self): for i in range(101): - time.sleep(0.05) # 模拟数据加载过程 + time.sleep(0.01) # 模拟数据加载过程 self.progress.emit(i) class LoadingDialog(QDialog): diff --git a/UI/SearchAddressWidget.py b/UI/SearchAddressWidget.py index ae99d2f..629ec60 100644 --- a/UI/SearchAddressWidget.py +++ b/UI/SearchAddressWidget.py @@ -22,6 +22,8 @@ class CustomProgressBar(QProgressBar): return f"{currentValue}/{maxValue}" + + class SearchAddressWidget(QWidget): def __init__(self, deviceAddressEdit): super().__init__() @@ -48,7 +50,7 @@ class SearchAddressWidget(QWidget): self.confirmBtn.clicked.connect(self.onConfirm) self.cancelBtn = QPushButton('取消') - + self.bottomLayout.addWidget(self.confirmBtn) self.bottomLayout.addWidget(QSplitter()) self.bottomLayout.addWidget(self.cancelBtn) @@ -61,8 +63,8 @@ class SearchAddressWidget(QWidget): self.setWindowTitle('从站地址查找') self.test = DPV1Master('192.168.3.10', 502) - self.test.searchSlave(self.updateProgress) - self.cancelBtn.clicked.connect(self.test.closeThread) + self.test.searchMaster(self.updateProgress) + self.cancelBtn.clicked.connect(self.cancelSearch) # self.timer = QTimer() # self.timer.timeout.connect(self.updateProgress) # self.timer.start(500) @@ -73,8 +75,6 @@ class SearchAddressWidget(QWidget): self.progressBar.setValue(address) if isSlave: self.addressListWidget.addItem(QListWidgetItem(str(address))) - # QApplication.processEvents() # 确保UI及时更新 - # QTimer.singleShot(100, lambda: None) # 暂停一小段时间,模拟任务执行时间 def onCellClicked(self, double = False): self.address = self.addressListWidget.currentItem().text() @@ -86,3 +86,6 @@ class SearchAddressWidget(QWidget): self.deviceAddressEdit.setText(self.address) self.close() + def cancelSearch(self): + self.test.closeThread + self.close() \ No newline at end of file