from PyQt5 import QtCore, QtWidgets 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 from utils import Globals from model.UserModel.UserManage import UserManage 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) # 悬停状态图标(稍微亮一些) 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.delBtn = QPushButton('批量删除') self.delBtn.setObjectName('delBtn') 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') self.proxy = QtCore.QSortFilterProxyModel(self) self.userView.proxy = self.proxy self.proxy.setSourceModel(self.userView.model) self.userView.setModel(self.proxy) Globals.setValue('userTable', self.userView) # [self.userView.model.append_data([x,'测试','测试','测试','测试','测试','测试','测试','测试','测试']) for x in range(10)] # self.model = VarTableModel(self.dic['header'], self.dic['data']) # self.varView.setModel(self.model) self.gridLayout = QtWidgets.QGridLayout(self) self.gridLayout.addWidget(self.createBtn, 0, 0, 1, 1) self.gridLayout.addWidget(QSplitter(), 0, 1, 1, 21) # self.gridLayout.addWidget(self.importBtn, 0, 21, 1, 1) self.gridLayout.addWidget(self.delBtn, 0, 22, 1, 1) self.gridLayout.addWidget(self.userView, 1, 0, 10, 23) self.gridLayout.setSpacing(10) self.gridLayout.setContentsMargins(20, 30, 20, 20) self.t_list = User.select() #for i in self.t_list: # self.userView.model.append_data([i.id, i.userName, i.userPwd, i.description, i.createTime]) # self.comboBox.currentIndexChanged.connect(self.on_comboBox_currentIndexChanged) self.horizontalHeader = self.userView.horizontalHeader() self.horizontalHeader.sectionClicked.connect(self.on_view_horizontalHeader_sectionClicked) def createUser(self): self.userView.model.append_data(['', '', '', '', '', '0', '0', '0', '0', '']) def deleteUser(self): # print('sss', self.userView.model.checkList) check = [i for i,x in enumerate(self.userView.model.checkList) if x == 'Checked'] check.sort(reverse=True) for i in check: model = self.userView.model #checkrow = self.userView.model.checkList.index(i) # print(i) name = str(model.datas[i][1]) UserManage.deleteUser(name=name) model.remove_row(i) @QtCore.pyqtSlot(int) def on_view_horizontalHeader_sectionClicked(self, logicalIndex): self.logicalIndex = logicalIndex self.on_comboBox_currentIndexChanged(self.logicalIndex) menuName = '_' + str(logicalIndex) + 'Menu' if not hasattr(self, menuName): setattr(self, menuName, QtWidgets.QMenu(self)) self.menuValues = getattr(self, menuName) menuEdit = QtWidgets.QLineEdit() inputAction = QtWidgets.QWidgetAction(self.menuValues) inputAction.setDefaultWidget(menuEdit) self.menuValues.addAction(inputAction) menuEdit.textChanged.connect(self.on_lineEdit_textChanged) self.menuValues = getattr(self, menuName) self.romoveAction(self.menuValues) self.signalMapper = QtCore.QSignalMapper(self) self.menuValues.mouseReleaseEvent = self._menu_mouseReleaseEvent actionAll = QtWidgets.QAction("All", self) actionAll.triggered.connect(self.on_actionAll_triggered) actionAll.setProperty('canHide', True) actionAll.setCheckable(True) self.menuValues.addAction(actionAll) self.menuValues.addSeparator() valuesUnique = [self.proxy.data(self.proxy.index(row, self.logicalIndex)) for row in range(self.proxy.rowCount()) ] for actionNumber, actionName in enumerate(sorted(list(set(valuesUnique)))): action = QtWidgets.QAction(str(actionName), self) self.signalMapper.setMapping(action, actionNumber) action.triggered.connect(self.signalMapper.map) action.setCheckable(True) self.menuValues.addAction(action) self.signalMapper.mapped.connect(self.on_signalMapper_mapped) headerPos =self.userView.mapToGlobal(self.horizontalHeader.pos()) posY = headerPos.y() + self.horizontalHeader.height() posX = headerPos.x() + self.horizontalHeader.sectionPosition(self.logicalIndex) getattr(self, menuName).exec_(QtCore.QPoint(posX, posY)) @QtCore.pyqtSlot() def on_actionAll_triggered(self): # 显示全部 filterColumn = self.logicalIndex filterString = QtCore.QRegExp( "", QtCore.Qt.CaseInsensitive, QtCore.QRegExp.RegExp ) self.proxy.setFilterRegExp(filterString) self.proxy.setFilterKeyColumn(filterColumn) @QtCore.pyqtSlot(int) def on_signalMapper_mapped(self, i): # stringAction = self.signalMapper.mapping(i).text() stringActions = '|'.join([x.text() for x in getattr(self, '_' + str(self.logicalIndex) + 'Menu').actions() if x.isChecked()]) filterColumn = self.logicalIndex print(stringActions) filterString = QtCore.QRegExp( stringActions, QtCore.Qt.CaseSensitive, # QtCore.QRegExp.FixedString ) self.proxy.setFilterRegExp(filterString) self.proxy.setFilterKeyColumn(filterColumn) @QtCore.pyqtSlot(str) def on_lineEdit_textChanged(self, text): # 搜索框文字变化函数 search = QtCore.QRegExp( text, QtCore.Qt.CaseInsensitive, QtCore.QRegExp.RegExp ) self.proxy.setFilterRegExp(search) @QtCore.pyqtSlot(int) def on_comboBox_currentIndexChanged(self, index): self.proxy.setFilterKeyColumn(index) def _menu_mouseReleaseEvent(self, event): action = self.menuValues.actionAt(event.pos()) if not action: # 没有找到action就交给QMenu自己处理 return QtWidgets.QMenu.mouseReleaseEvent(self.menuValues, event) if action.property('canHide'): # 如果有该属性则给菜单自己处理 return QtWidgets.QMenu.mouseReleaseEvent(self.menuValues, event) # 找到了QAction则只触发Action action.activate(action.Trigger) def romoveAction(self, menu): # 删除输入框之外的按钮1 for action in menu.actions(): if type(action) != QtWidgets.QWidgetAction: menu.removeAction(action) def _checkAction(self): # 三个action都响应该函数 self.labelInfo.setText('\n'.join(['{}\t选中:{}'.format( action.text(), action.isChecked()) for action in self.menuValues.actions()])) if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) main = UserWidget() main.show() main.resize(400, 600) sys.exit(app.exec_())