逻辑代码
# -*- coding: utf-8 -*-
import sys,time,copy
from PyQt5.QtWidgets import QWidget,QApplication, QDesktopWidget,QTableWidgetItem
from QhTableWidgetQGN import Ui_QhTableWidgetQGN
from PyQt5.QtCore import Qt
from PyQt5 import QtCore, QtGui, QtWidgets
from QhQTableWidgetEx import * #导入自定义的表格控件扩展类
class QhTableWidgetQGNGUI(QWidget,Ui_QhTableWidgetQGN):
"""
GUI交互部分代码
"""
def __init__(self,qh_parent = None):
# super().__init__(qh_parent)
super(QhTableWidgetQGNGUI, self).__init__()
self.setupUi(self)
self.QhItemDataLis=[ # 表模型参数 [字段名,字段宽度 0代表默认120,是否可调节宽度0可 1否,数据结构]
['#',36,1,['QCHECKBOX',str(''),0,'0,0','',None,None]],
['操作',190,1,['QPUSHBUTTON',["执行","修改"],0,'0,0',['ZHIXING','XIUGAI'],None,None]],
['操作1',190,0,['QPUSHBUTTON',"执行",0,'0,0','ZHIXING',None,None]],
['默认数据',0,1,['NONE',str('阙辉'),0,'0,0','',None,None]],
['整型数据',0,1,['INT',526,0,'0,0','',None,None]],
['浮点数据',0,1,['FLOAT',526.13,0,'0,0','',None,None]],
['字符串类型',0,1,['STR',str('阙辉526'),0,'0,0','',None,None]],
['日期类型数据',0,1,['DATA',str("2024-12-12"),0,'0,0','',None,None]],
['自定义字符串',0,1,['OWNQLINEEDIT',"378899",5,'0,0','',None,None]],
['组合框控件',0,1,['QComboBox',str('阙辉526'),2,'0,0','',None,None]],
['采用扩展标签控件QLabelEx',300,0,['QLabel',str('阙辉'),2,'0,0','',None,None]],
['多行文本',0,0,['QTEXTEDIT',str('阙辉526\n QComboBox组合框控件, 参数3表示此组合框在字典dic_TableItemData KEY对应的列表(选择项)'),2,'0,0','',None,None]],
['任务名称',120,0,['INT',str('QueHui'),0,'0,0','',None,None]],
['任务ID',120,0,['INT',str(''),0,'0,0','',None,None]],
['任务类型',100,1,['QCOMBOBOX',str(''),1,'0,0','',None,None]],
['日期YYYY-MM-DD',138,1,['DATE',str(''),0,'0,0','',None,None]],
['时',56,1,['INT',str(''),0,'0,0','',None,None]],
['分',56,1,['INT',str(''),0,'0,0','',None,None]],
['秒',56,1,['INT',str(''),0,'0,0','',None,None]],
['程序名',200,0,['STR',str(''),0,'0,0','',None,None]],
['任务状态',100,1,['STR',str(''),0,'0,0','',None,None]],
['运行状态',100,1,['STR',str(''),0,'0,0','',None,None]],
['累计次数',0,1,['INT',str(''),0,'0,0','',None,None]],
]
QhTableModel = copy.deepcopy(self.QhItemDataLis)
self.QhlstHead = [Qhrow[0] for Qhrow in QhTableModel] # 表头字段:支持动态增加
self.QhColwidthLs = [[Qhi,Qhrow[1]] for Qhi,Qhrow in enumerate(QhTableModel)] # 自定义列宽
self.QhIsResizeLs = [[Qhi,Qhrow[2]] for Qhi,Qhrow in enumerate(QhTableModel)] # 自定义不可编辑列
self.QhHeaderTableWidget = QhQTableWidgetEx(self.QhHeaderWidgetTB,
QhrowNum=1,
QhlstHead=self.QhlstHead,
QhColwidthLs=self.QhColwidthLs,
QhIsResizeLs=self.QhIsResizeLs,
QhFreeCol=3)
self.QhHeaderTableWidget.setRowHeight(0, 37)
# 隐藏头表横竖滚动条 阙辉
self.QhHeaderTableWidget.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.QhHeaderTableWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.gridLayout_6.addWidget(self.QhHeaderTableWidget, 0, 0, 1, 1)
self.QhMainTableWidget = QhQTableWidgetEx(self.QhMainWidgetTB,
QhrowNum=30,
QhlstHead=self.QhlstHead,
QhColwidthLs=self.QhColwidthLs,
QhIsResizeLs=self.QhIsResizeLs,
QhFreeCol=3)
# 隐藏主表表头信息 阙辉
# self.QhMainTableWidget.horizontalHeader().hide()
# self.QhMainTableWidget.QhfreezeTableWidget.horizontalHeader().hide()
self.gridLayout_5.addWidget(self.QhMainTableWidget, 0, 0, 1, 1)
# 横滚动条联动 阙辉
self.QhMainTableWidget.horizontalScrollBar().valueChanged.connect(self.QhHeaderTableWidget.horizontalScrollBar().setValue)
self.QhHeaderTableWidget.horizontalScrollBar().valueChanged.connect(self.QhMainTableWidget.horizontalScrollBar().setValue)
# 列宽联动 阙辉
self.QhHeaderTableWidget.horizontalHeader().sectionResized.connect(self.QhupdateMainSectionWidth)
self.QhMainTableWidget.horizontalHeader().sectionResized.connect(self.QhupdateHeaderSectionWidth)
# 上下列位置保持一一致,设置垂直滚动条一直存在 阙辉
self.QhHeaderTableWidget.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.QhMainTableWidget.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.QhHeaderTableWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
# self.QhButtonTBCX01.clicked.connect(self.Qhffff)
def QhupdateMainSectionWidth(self, logicalIndex, oldSize, newSize):
self.QhMainTableWidget.setColumnWidth(logicalIndex, newSize)
def QhupdateHeaderSectionWidth(self, logicalIndex, oldSize, newSize):
self.QhHeaderTableWidget.setColumnWidth(logicalIndex, newSize)
# def QhUpdateRightZW(self):
# QhWidthR = self.verticalHeader().width()
# self.QhframeZhanWei01.setMinimumSize(QtCore.QSize(QhWidthR, 10))
# self.QhframeZhanWei01.setMaximumSize(QtCore.QSize(QhWidthR, 10))
# def resizeEvent(self, event):
# # 冻结列 逻辑重写
# # 当表格大小发生变化时,更新冻结表格的位置和大小
# # 阙辉
# # self.QhframeZhanWei01.resize(int(20),10)
# super().resizeEvent(event)
# def Qhffff(self):
# print(self.QhMainTableWidget.verticalHeader().width())
if __name__ == "__main__":
qh_app = QApplication(sys.argv) # 创建应用实例 # 创建应用实例
qh_MyWindows = QhTableWidgetQGNGUI() # 创建窗口实例
qh_MyWindows.show() # 显示窗口
qh_n = qh_app.exec() # 执行exec()方法,进入事件循环,如果遇到窗口退出命令,返回整数qh_n
print(qh_n) # 输出输出关闭事件返回的整数
try: # 捕获程序退出事件
sys.exit(qh_n) # 通知python系统,结束程序运行
except SystemExit:
print("请在此做一些其他工作。") # python解释器停止执行前的工作
ui代码
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'QhTableWidgetQGN.ui'
#
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_QhTableWidgetQGN(object):
def setupUi(self, QhTableWidgetQGN):
QhTableWidgetQGN.setObjectName("QhTableWidgetQGN")
QhTableWidgetQGN.resize(965, 652)
QhTableWidgetQGN.setStyleSheet("QScrollBar:vertical {\n"
" border: none; /* 移除边框,如果需要的话 */\n"
" width: 15px; /* 设置滚动条的宽度 */\n"
" margin:0px 0 0px 0; /*为滚动条区域预留空间,这里22px是上下按钮的高度(假设) */\n"
"}\n"
"\n"
"\n"
"")
self.gridLayout = QtWidgets.QGridLayout(QhTableWidgetQGN)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setSpacing(0)
self.gridLayout.setObjectName("gridLayout")
self.QhHeaderWidgetQ = QtWidgets.QWidget(QhTableWidgetQGN)
self.QhHeaderWidgetQ.setMinimumSize(QtCore.QSize(0, 108))
self.QhHeaderWidgetQ.setMaximumSize(QtCore.QSize(16777215, 108))
self.QhHeaderWidgetQ.setStyleSheet("")
self.QhHeaderWidgetQ.setObjectName("QhHeaderWidgetQ")
self.gridLayout_2 = QtWidgets.QGridLayout(self.QhHeaderWidgetQ)
self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
self.gridLayout_2.setSpacing(0)
self.gridLayout_2.setObjectName("gridLayout_2")
self.QhHeaderWidgetGN = QtWidgets.QWidget(self.QhHeaderWidgetQ)
self.QhHeaderWidgetGN.setMinimumSize(QtCore.QSize(0, 40))
self.QhHeaderWidgetGN.setMaximumSize(QtCore.QSize(16777215, 40))
self.QhHeaderWidgetGN.setStyleSheet("")
self.QhHeaderWidgetGN.setObjectName("QhHeaderWidgetGN")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.QhHeaderWidgetGN)
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_2.setSpacing(0)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.QhPageWidgetCZ01 = QtWidgets.QWidget(self.QhHeaderWidgetGN)
self.QhPageWidgetCZ01.setMinimumSize(QtCore.QSize(0, 40))
self.QhPageWidgetCZ01.setMaximumSize(QtCore.QSize(16777215, 40))
self.QhPageWidgetCZ01.setObjectName("QhPageWidgetCZ01")
self.gridLayout_3 = QtWidgets.QGridLayout(self.QhPageWidgetCZ01)
self.gridLayout_3.setContentsMargins(-1, 5, -1, 5)
self.gridLayout_3.setObjectName("gridLayout_3")
self.widget_ZhanWei01 = QtWidgets.QWidget(self.QhPageWidgetCZ01)
self.widget_ZhanWei01.setMinimumSize(QtCore.QSize(0, 30))
self.widget_ZhanWei01.setMaximumSize(QtCore.QSize(16777215, 30))
self.widget_ZhanWei01.setObjectName("widget_ZhanWei01")
self.gridLayout_3.addWidget(self.widget_ZhanWei01, 0, 5, 1, 1)
self.QhpushButtonUp01 = QtWidgets.QPushButton(self.QhPageWidgetCZ01)
self.QhpushButtonUp01.setMinimumSize(QtCore.QSize(30, 30))
self.QhpushButtonUp01.setMaximumSize(QtCore.QSize(30, 30))
self.QhpushButtonUp01.setStyleSheet("QPushButton{border-image: url(:/QhImage/QhImage/QhDown01.png);border-radius: 5px; \n"
"}QPushButton:hover{border-image: url(:/QhImage/QhImage/QhDown05.png);border-radius: 5px;\n"
"}QPushButton:checked{color:#fff;border-color:#66b1ff;background-color: #66b1ff;\n"
"}QPushButton:pressed{color:#fff;border-color: #3a8ee6;background-color: #3a8ee6;\n"
"}\n"
"")
self.QhpushButtonUp01.setText("")
self.QhpushButtonUp01.setObjectName("QhpushButtonUp01")
self.gridLayout_3.addWidget(self.QhpushButtonUp01, 0, 0, 1, 1)
self.QhCobxPageYM01 = QtWidgets.QComboBox(self.QhPageWidgetCZ01)
self.QhCobxPageYM01.setMinimumSize(QtCore.QSize(60, 30))
self.QhCobxPageYM01.setMaximumSize(QtCore.QSize(16777215, 30))
self.QhCobxPageYM01.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContents)
self.QhCobxPageYM01.setObjectName("QhCobxPageYM01")
self.gridLayout_3.addWidget(self.QhCobxPageYM01, 0, 1, 1, 1)
self.QhLabelPageCount = QtWidgets.QLabel(self.QhPageWidgetCZ01)
self.QhLabelPageCount.setMinimumSize(QtCore.QSize(0, 30))
self.QhLabelPageCount.setMaximumSize(QtCore.QSize(16777215, 30))
self.QhLabelPageCount.setStyleSheet("QLabel {\n"
" color: blue; /* 设置字体颜色为红色 */\n"
" font-weight: bold; /* 设置字体为加粗 */\n"
"}")
self.QhLabelPageCount.setAlignment(QtCore.Qt.AlignCenter)
self.QhLabelPageCount.setObjectName("QhLabelPageCount")
self.gridLayout_3.addWidget(self.QhLabelPageCount, 0, 4, 1, 1)
self.QhpushButtonDown01 = QtWidgets.QPushButton(self.QhPageWidgetCZ01)
self.QhpushButtonDown01.setMinimumSize(QtCore.QSize(30, 30))
self.QhpushButtonDown01.setMaximumSize(QtCore.QSize(30, 30))
self.QhpushButtonDown01.setStyleSheet("QPushButton{border-image: url(:/QhImage/QhImage/QhUp01.png);border-radius: 5px; \n"
"}QPushButton:hover{border-image: url(:/QhImage/QhImage/QhUp05.png);border-radius: 5px;\n"
"}QPushButton:checked{color:#fff;border-color:#66b1ff;background-color: #66b1ff;\n"
"}QPushButton:pressed{color:#fff;border-color: #3a8ee6;background-color: #3a8ee6;\n"
"}\n"
"")
self.QhpushButtonDown01.setText("")
self.QhpushButtonDown01.setObjectName("QhpushButtonDown01")
self.gridLayout_3.addWidget(self.QhpushButtonDown01, 0, 2, 1, 1)
self.QhCobxPageC = QtWidgets.QComboBox(self.QhPageWidgetCZ01)
self.QhCobxPageC.setMinimumSize(QtCore.QSize(99, 30))
self.QhCobxPageC.setMaximumSize(QtCore.QSize(16777215, 30))
self.QhCobxPageC.setLayoutDirection(QtCore.Qt.LeftToRight)
self.QhCobxPageC.setCurrentText("")
self.QhCobxPageC.setObjectName("QhCobxPageC")
self.gridLayout_3.addWidget(self.QhCobxPageC, 0, 3, 1, 1)
self.horizontalLayout_2.addWidget(self.QhPageWidgetCZ01)
self.widget_ZhanWei02 = QtWidgets.QWidget(self.QhHeaderWidgetGN)
self.widget_ZhanWei02.setMinimumSize(QtCore.QSize(0, 30))
self.widget_ZhanWei02.setMaximumSize(QtCore.QSize(16777215, 30))
self.widget_ZhanWei02.setObjectName("widget_ZhanWei02")
self.horizontalLayout_2.addWidget(self.widget_ZhanWei02)
self.QhButwidgetGN = QtWidgets.QWidget(self.QhHeaderWidgetGN)
self.QhButwidgetGN.setMinimumSize(QtCore.QSize(268, 40))
self.QhButwidgetGN.setMaximumSize(QtCore.QSize(268, 40))
self.QhButwidgetGN.setObjectName("QhButwidgetGN")
self.gridLayout_4 = QtWidgets.QGridLayout(self.QhButwidgetGN)
self.gridLayout_4.setContentsMargins(-1, 5, -1, 5)
self.gridLayout_4.setObjectName("gridLayout_4")
self.QhButtonTBAdd01 = QtWidgets.QPushButton(self.QhButwidgetGN)
self.QhButtonTBAdd01.setMinimumSize(QtCore.QSize(68, 30))
self.QhButtonTBAdd01.setMaximumSize(QtCore.QSize(68, 30))
self.QhButtonTBAdd01.setStyleSheet("QPushButton{color:#fff;background-color:#67c23a;border: 1px solid #67c23a;border-radius: 10px;\n"
"}QPushButton:hover{color:#fff;border-color:#85ce61;background-color:#85ce61;\n"
"}QPushButton:checked{color:#fff;border-color:#85ce61;background-color: #85ce61;\n"
"}QPushButton:pressed{color:#fff;border-color: #5daf34;background-color: #5daf34;\n"
"}\n"
"")
self.QhButtonTBAdd01.setObjectName("QhButtonTBAdd01")
self.gridLayout_4.addWidget(self.QhButtonTBAdd01, 0, 1, 1, 1)
self.QhButtonTBCX01 = QtWidgets.QPushButton(self.QhButwidgetGN)
self.QhButtonTBCX01.setMinimumSize(QtCore.QSize(68, 30))
self.QhButtonTBCX01.setMaximumSize(QtCore.QSize(68, 30))
self.QhButtonTBCX01.setStyleSheet("QPushButton{color:#fff;background-color:#409eff;border: 1px solid #409eff;border-radius: 10px;\n"
"}QPushButton:hover{color:#fff;border-color:#66b1ff;background-color:#66b1ff;\n"
"}QPushButton:checked{color:#fff;border-color:#66b1ff;background-color: #66b1ff;\n"
"}QPushButton:pressed{color:#fff;border-color: #3a8ee6;background-color: #3a8ee6;\n"
"}\n"
"")
self.QhButtonTBCX01.setObjectName("QhButtonTBCX01")
self.gridLayout_4.addWidget(self.QhButtonTBCX01, 0, 0, 1, 1)
self.QhButtonTBDel01 = QtWidgets.QPushButton(self.QhButwidgetGN)
self.QhButtonTBDel01.setMinimumSize(QtCore.QSize(68, 30))
self.QhButtonTBDel01.setMaximumSize(QtCore.QSize(68, 30))
self.QhButtonTBDel01.setStyleSheet("QPushButton{color:#fff;background-color:#f56c6c;border: 1px solid #f56c6c;border-radius: 10px;\n"
"}QPushButton:hover{color:#fff;border-color:#f78989;background-color:#f78989;\n"
"}QPushButton:checked{color:#fff;border-color:#f78989;background-color: #f78989;\n"
"}QPushButton:pressed{color:#fff;border-color: #dd6161;background-color: #dd6161;\n"
"}\n"
"")
self.QhButtonTBDel01.setObjectName("QhButtonTBDel01")
self.gridLayout_4.addWidget(self.QhButtonTBDel01, 0, 2, 1, 1)
self.horizontalLayout_2.addWidget(self.QhButwidgetGN)
self.gridLayout_2.addWidget(self.QhHeaderWidgetGN, 0, 0, 1, 1)
self.QhHeaderWidgetTB = QtWidgets.QWidget(self.QhHeaderWidgetQ)
self.QhHeaderWidgetTB.setMinimumSize(QtCore.QSize(0, 68))
self.QhHeaderWidgetTB.setMaximumSize(QtCore.QSize(16777215, 68))
self.QhHeaderWidgetTB.setObjectName("QhHeaderWidgetTB")
self.gridLayout_6 = QtWidgets.QGridLayout(self.QhHeaderWidgetTB)
self.gridLayout_6.setContentsMargins(0, 0, 0, 0)
self.gridLayout_6.setSpacing(0)
self.gridLayout_6.setObjectName("gridLayout_6")
self.QhHeaderTableWidget = QtWidgets.QTableWidget(self.QhHeaderWidgetTB)
self.QhHeaderTableWidget.setMinimumSize(QtCore.QSize(0, 80))
self.QhHeaderTableWidget.setMaximumSize(QtCore.QSize(16777215, 80))
self.QhHeaderTableWidget.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.QhHeaderTableWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.QhHeaderTableWidget.setRowCount(1)
self.QhHeaderTableWidget.setColumnCount(30)
self.QhHeaderTableWidget.setObjectName("QhHeaderTableWidget")
self.gridLayout_6.addWidget(self.QhHeaderTableWidget, 0, 0, 1, 1)
self.gridLayout_2.addWidget(self.QhHeaderWidgetTB, 1, 0, 1, 1)
self.gridLayout.addWidget(self.QhHeaderWidgetQ, 0, 0, 1, 1)
self.QhMainWidgetTB = QtWidgets.QWidget(QhTableWidgetQGN)
self.QhMainWidgetTB.setObjectName("QhMainWidgetTB")
self.gridLayout_5 = QtWidgets.QGridLayout(self.QhMainWidgetTB)
self.gridLayout_5.setContentsMargins(0, 0, 0, 0)
self.gridLayout_5.setSpacing(0)
self.gridLayout_5.setObjectName("gridLayout_5")
self.QhMainTableWidget = QtWidgets.QTableWidget(self.QhMainWidgetTB)
self.QhMainTableWidget.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.QhMainTableWidget.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustIgnored)
self.QhMainTableWidget.setRowCount(1)
self.QhMainTableWidget.setColumnCount(3)
self.QhMainTableWidget.setObjectName("QhMainTableWidget")
self.QhMainTableWidget.verticalHeader().setDefaultSectionSize(37)
self.QhMainTableWidget.verticalHeader().setMinimumSectionSize(30)
self.gridLayout_5.addWidget(self.QhMainTableWidget, 0, 0, 1, 1)
self.gridLayout.addWidget(self.QhMainWidgetTB, 1, 0, 1, 1)
self.retranslateUi(QhTableWidgetQGN)
QtCore.QMetaObject.connectSlotsByName(QhTableWidgetQGN)
def retranslateUi(self, QhTableWidgetQGN):
_translate = QtCore.QCoreApplication.translate
QhTableWidgetQGN.setWindowTitle(_translate("QhTableWidgetQGN", "Form"))
self.QhLabelPageCount.setText(_translate("QhTableWidgetQGN", "共9页,共1000000行"))
self.QhButtonTBAdd01.setText(_translate("QhTableWidgetQGN", "增加"))
self.QhButtonTBCX01.setText(_translate("QhTableWidgetQGN", "查询"))
self.QhButtonTBDel01.setText(_translate("QhTableWidgetQGN", "删除"))
import QhTableQGN_rc
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QhTableWidgetQGN</class>
<widget class="QWidget" name="QhTableWidgetQGN">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>965</width>
<height>652</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="styleSheet">
<string notr="true">QScrollBar:vertical {
border: none; /* 移除边框,如果需要的话 */
width: 15px; /* 设置滚动条的宽度 */
margin:0px 0 0px 0; /*为滚动条区域预留空间,这里22px是上下按钮的高度(假设) */
}
</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QWidget" name="QhHeaderWidgetQ" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>108</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>108</height>
</size>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QWidget" name="QhHeaderWidgetGN" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>40</height>
</size>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="QhPageWidgetCZ01" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>40</height>
</size>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<property name="topMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item row="0" column="5">
<widget class="QWidget" name="widget_ZhanWei01" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>30</height>
</size>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="QhpushButtonUp01">
<property name="minimumSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{border-image: url(:/QhImage/QhImage/QhDown01.png);border-radius: 5px;
}QPushButton:hover{border-image: url(:/QhImage/QhImage/QhDown05.png);border-radius: 5px;
}QPushButton:checked{color:#fff;border-color:#66b1ff;background-color: #66b1ff;
}QPushButton:pressed{color:#fff;border-color: #3a8ee6;background-color: #3a8ee6;
}
</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="QhCobxPageYM01">
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>30</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="QhLabelPageCount">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>30</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QLabel {
color: blue; /* 设置字体颜色为红色 */
font-weight: bold; /* 设置字体为加粗 */
}</string>
</property>
<property name="text">
<string>共9页,共1000000行</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="QhpushButtonDown01">
<property name="minimumSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{border-image: url(:/QhImage/QhImage/QhUp01.png);border-radius: 5px;
}QPushButton:hover{border-image: url(:/QhImage/QhImage/QhUp05.png);border-radius: 5px;
}QPushButton:checked{color:#fff;border-color:#66b1ff;background-color: #66b1ff;
}QPushButton:pressed{color:#fff;border-color: #3a8ee6;background-color: #3a8ee6;
}
</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QComboBox" name="QhCobxPageC">
<property name="minimumSize">
<size>
<width>99</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>30</height>
</size>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="currentText">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_ZhanWei02" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>30</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="QhButwidgetGN" native="true">
<property name="minimumSize">
<size>
<width>268</width>
<height>40</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>268</width>
<height>40</height>
</size>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<property name="topMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item row="0" column="1">
<widget class="QPushButton" name="QhButtonTBAdd01">
<property name="minimumSize">
<size>
<width>68</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>68</width>
<height>30</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{color:#fff;background-color:#67c23a;border: 1px solid #67c23a;border-radius: 10px;
}QPushButton:hover{color:#fff;border-color:#85ce61;background-color:#85ce61;
}QPushButton:checked{color:#fff;border-color:#85ce61;background-color: #85ce61;
}QPushButton:pressed{color:#fff;border-color: #5daf34;background-color: #5daf34;
}
</string>
</property>
<property name="text">
<string>增加</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="QhButtonTBCX01">
<property name="minimumSize">
<size>
<width>68</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>68</width>
<height>30</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{color:#fff;background-color:#409eff;border: 1px solid #409eff;border-radius: 10px;
}QPushButton:hover{color:#fff;border-color:#66b1ff;background-color:#66b1ff;
}QPushButton:checked{color:#fff;border-color:#66b1ff;background-color: #66b1ff;
}QPushButton:pressed{color:#fff;border-color: #3a8ee6;background-color: #3a8ee6;
}
</string>
</property>
<property name="text">
<string>查询</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="QhButtonTBDel01">
<property name="minimumSize">
<size>
<width>68</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>68</width>
<height>30</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{color:#fff;background-color:#f56c6c;border: 1px solid #f56c6c;border-radius: 10px;
}QPushButton:hover{color:#fff;border-color:#f78989;background-color:#f78989;
}QPushButton:checked{color:#fff;border-color:#f78989;background-color: #f78989;
}QPushButton:pressed{color:#fff;border-color: #dd6161;background-color: #dd6161;
}
</string>
</property>
<property name="text">
<string>删除</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QWidget" name="QhHeaderWidgetTB" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>68</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>68</height>
</size>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QTableWidget" name="QhHeaderTableWidget">
<property name="minimumSize">
<size>
<width>0</width>
<height>80</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>80</height>
</size>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="rowCount">
<number>1</number>
</property>
<property name="columnCount">
<number>30</number>
</property>
<row/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
<column/>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QWidget" name="QhMainWidgetTB" native="true">
<layout class="QGridLayout" name="gridLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QTableWidget" name="QhMainTableWidget">
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustIgnored</enum>
</property>
<property name="rowCount">
<number>1</number>
</property>
<property name="columnCount">
<number>3</number>
</property>
<attribute name="verticalHeaderDefaultSectionSize">
<number>37</number>
</attribute>
<attribute name="verticalHeaderMinimumSectionSize">
<number>30</number>
</attribute>
<row/>
<column/>
<column/>
<column/>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="QhTableQGN.qrc"/>
</resources>
<connections/>
</ui>
拓展表格
#模块名:QhQTableWidgetEx.py:将QT5/6的表格控件窗体扩展子类
#包含类名: QhQTableWidgetEx: 继承QTableWidget类的扩展类:支持表格中的单元格可加载多种控件等功能
# QLabelEx:继承QLabel类的扩展类:可作为表格单元格的一个控件,自动加载图片,动画等功能
# QHeaderViewEx:可在表格列头显示一个复选框控件,用于全选一项组合框的功能
# OwnQTextEdit:继承QTextEdit类的扩展类:可作为表格单元格的一个控件,主要是去除了默认的粗边框,其他功能自行扩充
# OwnQLineEdit:继承QLineEdit类的扩展类:可作为表格单元格的一个控件,可自定义掩码,如密码等格式化输入
import os,copy
from PyQt5 import *
from PyQt5 import QtCore
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtGui import QMovie
from PyQt5.QtCore import QByteArray
from PyQt5.QtWidgets import QTableWidget, QHeaderView,QTableWidgetItem,\
QCheckBox,QWidget,QLabel,QPushButton,QComboBox,QLineEdit,QTextEdit
from PyQt5.QtGui import QBrush, QColor
from PyQt5.QtCore import Qt
class QhQTableWidgetEx(QTableWidget):
#'NONE':默认数据,采用默认表格单元格,不在表格位置创建任何依附控件()
#'INT': 整型数据,采用默认表格单元格
#'FLOAT':浮点数据,采用默认表格单元格
#'STR':字符串类型,采用默认表格单元格
#'DATA':日期类型数据,采用单行OwnQLineEdit控件(设置掩码)
#'OWNQLINEEDIT':自定义字符串,采用单行OwnQLineEdit控件
#'QComboBox':组合框控件, 参数3表示此组合框在字典dic_TableItemData KEY对应的列表(选择项)
#'QCheckBox':复选框控件, 参数3无意义 无法调节宽度 涉及时就必须计算好宽度
#'QLabel':采用扩展标签控件QLabelEx, 参数3表示标签可选用的图象列表,在字典dic_TableItemData KEY对应的二进制数据(已将文件加载到内存后)
#'QPushButtom':采用按纽, 参数3表示按纽选用图标在字典dic_TableItemData KEY对应的二进制数据(已将文件加载到内存后)
DEF_ITEMDATA=['STR','',0,'0,0','',None,None] #默认单元格绑定的数据格式:[类型,值,掩码ID,索引(row,col),对象名str,对象,对象]
#定义表格控件要用的的组合框等下拉列表要用到的数据,为单元格列表对象的第2个元素值
dic_TableItemData={0:[None], #0: KEY容错处理用
1:['选项01','选项02','选项03'], #1:示例-供表格中的下拉组合框用,选择项列表1
2:['选项A','选项B','选项C','选项D'], #2:示例-供表格中的下拉组合框用,选择项列表2
3:['1.png','2.png','3.png','4.png'], #3:示例-供表格中的标签、按纽等使用,显示图象
4:'999999999999;#', #4:示例-供表格中的自定义编辑框使用的掩码
5:'0000-00-00', #5:示例-供表格中的自定义编辑框使用的掩码
6:''
}
scrollbar_value = pyqtSignal(int)
#初始化对角需传递的参数为父类:
def __init__(self,
parent, # 父类
QhrowNum, # 行数
QhlstHead, # 表头字段列表
QhColwidthLs, # 自定义列宽列表
QhIsResizeLs, # 自定义不可编辑列列表
# QhTableModel, # 表格模型 # 表模型参数 [[字段名,字段宽度 0代表默认120,是否可调节宽度0可 1否,数据结构],...]
QhFreeCol=3, # 冻结列数
):
super(QTableWidget, self).__init__(parent)
# 初始化数据
self.QhCheckBoxflag = False
self.QhFreeCol = QhFreeCol # 冻结列数
self.QhlstHead = QhlstHead # 表头字段:支持动态增加
self.QhColwidthLs = QhColwidthLs # 自定义列宽
self.QhIsResizeLs = QhIsResizeLs # 自定义不可编辑列
self.QhCheckBoxList = [] # 复选框列表 仅限于第1列,0列 其他暂不支持
self.curRowCount=QhrowNum #表格当前的总行数
self.curColCount=len(self.QhlstHead) #表格当前的总列数
self.QhitemData=[[[],[]],[[],[]]] #定义同表格绑定的列表
self.QhitemData.clear()
# self.Qhitem_one=copy.deepcopy(QhQTableWidgetEx.DEF_ITEMDATA) #对列表要用deepcopy来赋值,防止列表变量默认是同内存
# for Qhrow in range(QhrowNum):
# Qhitem_onerow=[['STR','',0,'0,0','',None,None]]
# Qhitem_onerow.clear()
# for Qhcol in range(self.curColCount):
# self.Qhitem_one[0]=str('STR') # 数据类型
# self.Qhitem_one[1]=str(Qhrow) # 数据值
# self.Qhitem_one[3]=str("{},{}".format(Qhrow,Qhcol)) # 数据索引 映射的时候更新
# self.Qhitem_one[4]=str('') # 对象名
# Qhitem_onerow.append(copy.deepcopy(self.Qhitem_one))
# self.QhitemData.append(copy.deepcopy(Qhitem_onerow))
self.setColumnCount(self.curColCount) #设置表格列数
self.QhsetColumnWidth() # 设置列宽 此方法不能重写 否则报错 QhupdateFrozenTableGeometry 有调用原本列宽
self.QhinitTable() # 表格设置
self.QhFreezeTableWidget() # 初始化冻结列的表格
self.setRowCount(self.curRowCount) # 设置表格行数 重写逻辑放冻结表初始化后
self.setAlternatingRowColors(True) # 设置交替行颜色 重写逻辑放冻结表初始化后
self.setHorizontalHeaderLabels(self.QhlstHead) # 设置行表头字段名 重写逻辑放冻结表初始化后
self.QhsetSectionResizeModeLis() # 设置列宽不可编辑 涉及冻结表逻辑放冻结表初始化后
# 隐藏表格的垂直表头(通常是行号)。
self.verticalHeader().hide() # 隐藏表格的垂直表头(通常是行号)。
# self.QhFreeTest() # 冻结表测试
#对表格进一步初始化
def QhinitTable(self):
# 此方法主要是对表格样式进项设置 可拓展
# 阙辉
# self.setTableHeader(QFrame.Box,QFrame.Sunken,'red','greenyellow') #设置表格头内容和样式
# self.setTableHeader(QFrame.Box,QFrame.Sunken,'black','white')
# self.setAlternatingRowColors(bAlRow) # 交替行颜色
#self.setTableData() #设置表格初始化数据:在主窗体中调用
self.alignFlags=Qt.AlignVCenter | Qt.AlignHCenter
# self.bkCol=QColor(255,255,255) #如设置不透明时的标签背景颜色
# self.setFont(font)
# palette = QPalette()
# self.fontCol=fcolor #字体颜色
# palette.setColor(QPalette.WindowText, self.fontCol) #设置字体颜色
# self.setPalette(palette)
# header = self.horizontalHeader()
# header.setSectionResizeMode(QHeaderView.Fixed)
print(2)
def QhFreezeTableWidget(self):
# 初始化冻结列的表格
if self.QhFreeCol==0:return
# 初始化冻结列的表格
self.QhfreezeTableWidget = QTableWidget(self)
self.QhfreezeTableWidget.setColumnCount(self.QhFreeCol) # 假设我们要冻结第一列
# self.QhfreezeTableWidget.setRowCount(100) # 假设我们要冻结第一列
# self.QhfreezeTableWidget.setHorizontalHeaderLabels(['Frozen Column'])
# 将表格的选择模式设置为 QTableWidget.NoSelection,这意味着用户无法在表格中进行选择操作。
self.QhfreezeTableWidget.setSelectionMode(QTableWidget.NoSelection)
# 设置表格的焦点策略为 Qt.NoFocus,这意味着表格控件不会接收键盘焦点。
self.QhfreezeTableWidget.setFocusPolicy(Qt.NoFocus)
# 隐藏表格的垂直表头(通常是行号)。
self.QhfreezeTableWidget.verticalHeader().hide()
# 设置表格的垂直滚动条策略为 Qt.ScrollBarAlwaysOff,这意味着无论内容是否超出可视区域,垂直滚动条都不会显示。
self.QhfreezeTableWidget.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.QhfreezeTableWidget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
# 设置表格的样式,保留原有样式,增加右边框 冻结分割线
QhFreeTabOldStyle = self.QhfreezeTableWidget.styleSheet()
QhFreeTabStyle = str("QTableWidget { border-top: none; border-bottom: none; border-left: none; border-right: 2px solid black;}")
QhFreeTabNewStyle = str(QhFreeTabOldStyle) + "\n" + QhFreeTabStyle
self.QhfreezeTableWidget.setStyleSheet(QhFreeTabNewStyle)
# 连接表格列宽度变化事件,更新冻结表格的列宽度
self.horizontalHeader().sectionResized.connect(self.QhupdateSectionWidth)
self.QhfreezeTableWidget.horizontalHeader().sectionResized.connect(self.QhupdateFuSectionWidth)
self.verticalHeader().sectionResized.connect(self.QhupdateSectionHeight)
# 连接滚动条事件,使两个表格同步滚动
self.verticalScrollBar().valueChanged.connect(self.QhfreezeTableWidget.verticalScrollBar().setValue)
self.horizontalScrollBar().valueChanged.connect(self.QhfreezeTableWidget.horizontalScrollBar().setValue)
self.QhfreezeTableWidget.verticalScrollBar().valueChanged.connect(self.verticalScrollBar().setValue)
self.verticalScrollBar().valueChanged.connect(self.QhfreezeTableWidget.verticalScrollBar().setValue)
# self.itemSelectionChanged.connect(self.QhfreezeTableWidget.on_item_selection_changed)
self.viewport().stackUnder(self.QhfreezeTableWidget)
self.QhupdateFrozenTableGeometry()
def QhFreeTest(self):
# 测试冻结列添加数据
for row in range(self.curRowCount):
for i in range(self.QhFreeCol):
item_text = "{}{}".format(str(row), str(i))
item = QTableWidgetItem(item_text)
self.QhfreezeTableWidget.setItem(row, i, item)
# def on_item_selection_changed(self):
# # 获取选中行的索引
# selected_rows = self.selectedIndexes()
# if not selected_rows:
# return
# # 假设我们只处理第一列被选中的情况,即整行被选中
# selected_row = selected_rows[0].row()
# # 获取选中行的数据
# for col in range(self.tableWidget1.columnCount()):
# item = self.item(selected_row, col)
# if item:
# # 将数据复制到第二个表格中对应的位置
# self.tableWidget2.setItem(selected_row, col, QTableWidgetItem(item.text()))
def QhupdateFrozenTableGeometry(self):
# 更新冻结表格的几何结构 超级重要
# 表格宽度
# 阙辉
Qhfreewidth = 0
for Qhi in range(self.QhFreeCol):
Qhfreewidth += self.columnWidth(Qhi)
self.QhfreezeTableWidget.setColumnWidth(Qhi,self.columnWidth(Qhi))
self.QhfreezeTableWidget.setGeometry(
self.verticalHeader().width() + self.frameWidth(), # X 坐标
self.frameWidth(), # Y 坐标
Qhfreewidth, # 宽度
self.viewport().height() + self.horizontalHeader().height() # 高度
)
def resizeEvent(self, event):
# 冻结列 逻辑重写
# 当表格大小发生变化时,更新冻结表格的位置和大小
# 阙辉
if self.QhFreeCol > 0:self.QhupdateFrozenTableGeometry()
super().resizeEvent(event)
def setAlternatingRowColors(self,QhIsSet=False):
# 冻结列 逻辑重写
# 设置表格的交替行颜色
# 阙辉
if not QhIsSet:return
if self.QhFreeCol > 0: self.QhfreezeTableWidget.setAlternatingRowColors(QhIsSet)
super().setAlternatingRowColors(QhIsSet)
def setHorizontalHeaderLabels(self, QhFliedLs):
if self.QhFreeCol > 0:
QhFliedFreeLs = QhFliedLs[:self.QhFreeCol]
self.QhfreezeTableWidget.setHorizontalHeaderLabels(QhFliedFreeLs)
super().setHorizontalHeaderLabels(QhFliedLs)
def setRowCount(self,QhRowCount):
# 冻结列 逻辑重写
# 设置表格的行数
# 阙辉
if self.QhFreeCol > 0: self.QhfreezeTableWidget.setRowCount(QhRowCount)
super().setRowCount(QhRowCount)
# def setColumnWidth(self,QhCol,QhWidth):
# # 冻结列 逻辑重写 此方法不能重写 否则报错 QhupdateFrozenTableGeometry 有调用原本列宽
# # 设置列宽 阙辉
# if self.QhFreeCol > 0: self.QhfreezeTableWidget.setColumnWidth(QhCol,QhWidth)
# super().setColumnWidth(QhCol,QhWidth)
def setRowHeight(self,QhCol,QhWidth):
# 冻结列 逻辑重写 此方法不能重写 否则报错 QhupdateFrozenTableGeometry 有调用原本列宽
# 设置列宽 阙辉
if self.QhFreeCol > 0: self.QhfreezeTableWidget.setRowHeight(QhCol,QhWidth)
super().setRowHeight(QhCol,QhWidth)
def insertRow(self, Qhrow):
# 冻结列 逻辑重写
# 插入行 阙辉
if self.QhFreeCol > 0:self.QhfreezeTableWidget.insertRow(Qhrow)
super().insertRow(Qhrow)
def QhGetitem(self, Qhrow, Qhcolumn):
# 冻结列 逻辑重写
# 获取指定行和列的单元格对象 阙辉
if Qhcolumn < self.QhFreeCol and self.QhFreeCol> 0:
# print("bbb",self.QhfreezeTableWidget.item(0, 2))
return self.QhfreezeTableWidget.item(Qhrow, Qhcolumn)
else:
# print("gg",super().item(0, 5))
return self.item(Qhrow, Qhcolumn)
def setItem(self, Qhrow, Qhcolumn, Qhitem):
# 冻结列 逻辑重写
# 设置指定行和列的单元格 阙辉
if self.QhFreeCol > 0 and Qhcolumn < self.QhFreeCol:
self.QhfreezeTableWidget.setItem(Qhrow, Qhcolumn, Qhitem)
else:
super().setItem(Qhrow, Qhcolumn, Qhitem)
def setCellWidget(self, Qhrow, Qhcolumn, Qhwightobj):
# 冻结列 逻辑重写
# 设置指定行和列的对象 阙辉
if self.QhFreeCol > 0 and Qhcolumn < self.QhFreeCol:
self.QhfreezeTableWidget.setCellWidget(Qhrow, Qhcolumn, Qhwightobj)
else:
super().setCellWidget(Qhrow, Qhcolumn, Qhwightobj)
def removeCellWidget(self, Qhrow, Qhcolumn):
# 冻结列 逻辑重写
# 移除指定行和列的对象 阙辉
if self.QhFreeCol > 0 and Qhcolumn < self.QhFreeCol:
self.QhfreezeTableWidget.removeCellWidget(Qhrow, Qhcolumn)
else:
super().removeCellWidget(Qhrow, Qhcolumn)
# def QhGetCheckBoxflag(self):
# # 冻结列 逻辑重写
# # 获取复选框状态 阙辉
# if self.QhFreeCol > 0 and Qhcolumn < self.QhFreeCol:
# self.QhfreezeTableWidget.setCellWidget(Qhrow, Qhcolumn, Qhwightobj)
# else:
# super().setCellWidget(Qhrow, Qhcolumn, Qhwightobj)
def verticalScrollbarValueChanged(self, value):
self.verticalScrollBar().setValue(value)
self.scrollbar_value.emit(value)
def QhupdateSectionWidth(self, logicalIndex, oldSize, newSize):
# 冻结列 逻辑重写
if self.QhFreeCol == 0: return
if logicalIndex <= self.QhFreeCol:
self.QhfreezeTableWidget.setColumnWidth(logicalIndex, newSize)
self.QhupdateFrozenTableGeometry()
def QhupdateFuSectionWidth(self, logicalIndex, oldSize, newSize):
if self.QhFreeCol == 0: return
super().setColumnWidth(logicalIndex, newSize)
self.QhupdateFrozenTableGeometry()
def QhupdateSectionHeight(self, logicalIndex, oldSize, newSize):
if self.QhFreeCol == 0: return
self.QhfreezeTableWidget.setRowHeight(logicalIndex, newSize)
def QhsetSectionResizeModeLis(self):
# 冻结列 逻辑重写
# 有冻结列时重合冻结表和原表重合列必须设置不可编辑 此限制已被攻破
# 设置列不可编辑 阙辉
if len(self.QhIsResizeLs) == 0 and self.QhFreeCol == 0 : return
self.Qhheader = self.horizontalHeader()
if self.QhFreeCol > 0:self.QhFreeheader = self.QhfreezeTableWidget.horizontalHeader()
# if self.QhFreeCol > 0:
# self.QhFreeheader = self.QhfreezeTableWidget.horizontalHeader()
# for Qhi in range(self.QhFreeCol):
# self.QhFreeheader.setSectionResizeMode(Qhi, QHeaderView.Fixed) # 冻结表设置不可编辑该列宽度
# self.Qhheader.setSectionResizeMode(Qhi, QHeaderView.Fixed) # 原表格设置不可编辑该列宽度
for QhRow in self.QhIsResizeLs:
col = QhRow[0]
QhIsResize = QhRow[1]
if QhIsResize == 1:
if col < self.QhFreeCol:self.QhFreeheader.setSectionResizeMode(col, QHeaderView.Fixed) # 冻结表设置不可编辑该列宽度
self.Qhheader.setSectionResizeMode(col, QHeaderView.Fixed) # 原表格设置不可编辑该列宽度
def QhsetColumnWidth(self):
# 冻结列 逻辑重写
# 设置列宽 阙辉
if len(self.QhColwidthLs) == 0 : return
for QhRow in self.QhColwidthLs:
col = QhRow[0]
QhWidth = int(QhRow[1])
if QhWidth == 0: QhWidth = 120 # 默认宽度
self.setColumnWidth(col,QhWidth)
#得到类字典指定key的值
def getDicKeyValue(self,keyID,defvalue=None):
lst_item = QhQTableWidgetEx.dic_TableItemData.get(keyID,defvalue) #用get函数来得到对应字典key的值,如果没有,得到默认值,防报错
return lst_item
def QhsetItemData(self,Qhrow,Qhcol,QhlstItemData):
# self.QhitemData
# QhbNew 如果为True 则表格置空 绑定数据还在
if(Qhrow>self.curRowCount-1 or Qhrow<0 and Qhcol>self.curColCount and Qhcol<0) :
print('行或列号有误')
return
# if not QhbNew:lstOrdData=copy.deepcopy(self.QhitemData[Qhrow][Qhcol]) #原始表格数据,设置后,后替换原单元格数据
self.QhitemData[Qhrow][Qhcol]=copy.deepcopy(QhlstItemData)
Qhtypestr=QhlstItemData[0].upper() # 数据类型大写
Qhitemtext=QhlstItemData[1] # 数据值
QhdicID=QhlstItemData[2] # 数据绑定ID
self.removeCellWidget(Qhrow,Qhcol) # 移除原位置上的单元格控件 逻辑重写
self.QhclearCell(Qhrow,Qhcol) # 此函数会清空绑定数据列表中的内容, 有重合功能 待验证
self.QhitemData[Qhrow][Qhcol][0] = Qhtypestr # 需对绑定的数据重新赋值 数据类型
self.QhitemData[Qhrow][Qhcol][1] = Qhitemtext # 需对绑定的数据重新赋值 数据值
self.QhitemData[Qhrow][Qhcol][3] = "{},{}".format(Qhrow,Qhcol) # 需对绑定的数据重新赋值 数据索引
if(Qhtypestr==None or Qhtypestr.upper()=='NONE'
or Qhtypestr=="INT" or Qhtypestr=="FLOAT" or
Qhtypestr=="STR" or Qhtypestr=="DATE"):
Qhitem = QTableWidgetItem(str(Qhitemtext))
self.setItem(Qhrow,Qhcol,Qhitem) #!!!!重要:必须用此行代码才真正初始化了非控件类的单元格,否则单元格可以录入数据,但实际值为None
else: #是控件类的单元格时
# 用于让控件居中
Qhwidget = QWidget()
Qhlayout = QHBoxLayout(Qhwidget)
Qhlayout.setContentsMargins(1, 1, 1, 1)
Qhlayout.setAlignment(Qt.AlignCenter)
self.setItem(Qhrow,Qhcol,None) #对控件类单元格,因控件覆盖在单元格上,应将原单元格设置为None,防止单元格有内容时同控件显示重叠
if Qhtypestr=="OWNQLINEEDIT" or Qhtypestr=="QLINEEDIT": #自定义编辑框控件,用掩码显示内容
Qhlineedit=OwnQLineEdit(self,'') #当前定义的是默认字符串类型:
QhitemobjName = "{}_{}_{}".format(Qhtypestr,Qhrow,Qhcol) # 按钮对象名称 记录按钮索引坐标
Qhlineedit.setObjectName(QhitemobjName)
self.QhitemData[Qhrow][Qhcol][4]=QhitemobjName # 需对绑定的数据重新赋值 数据对象名
if(QhdicID==4 or QhdicID==5): #只有指定的值才表示是有掩码的编辑框
mskstr = self.getDicKeyValue(QhdicID) #从字典中得到掩码字串
Qhlineedit.setEditMask(mskstr)
Qhlayout.addWidget(Qhlineedit)
self.setCellWidget(Qhrow,Qhcol,Qhwidget)
# if not QhbNew: Qhlineedit.setText(Qhitemtext)
elif Qhtypestr=="MUSTR" or Qhtypestr=="QTEXTEDIT":
#对多行文本,要支持多行文本
Qhtextedit=OwnQTextEdit(Qhitemtext)
QhitemobjName = "{}_{}_{}".format(Qhtypestr,Qhrow,Qhcol) # 按钮对象名称 记录按钮索引坐标
Qhtextedit.setObjectName(QhitemobjName)
self.QhitemData[Qhrow][Qhcol][4]=QhitemobjName # 需对绑定的数据重新赋值 数据对象名
self.QhitemData[Qhrow][Qhcol][4]=QhitemobjName
Qhlayout.addWidget(Qhtextedit)
self.setCellWidget(Qhrow,Qhcol,Qhwidget)
# if not QhbNew:Qhtextedit.setText(Qhitemtext)
elif Qhtypestr=="QCHECKBOX" :
#复选框控件
Qhcheckbox = QCheckBox(Qhitemtext) #创建按纽并设置文本
QhitemobjName = "{}_{}_{}".format(Qhtypestr,Qhrow,Qhcol) # 按钮对象名称 记录按钮索引坐标
Qhcheckbox.setObjectName(QhitemobjName)
# self.all_header0_chkbox.append(checkbox) #以支持在列表头点击复选框时可全选行头的复选框
self.QhitemData[Qhrow][Qhcol][4]=QhitemobjName
Qhcheckbox.clicked.connect(lambda state, Qhcheckbox=Qhcheckbox: self.checkbox_clicked0(Qhcheckbox)) # 连接信号槽
Qhlayout.addWidget(Qhcheckbox)
self.setCellWidget(Qhrow,Qhcol,Qhwidget) # 将按纽添加到表格的单元格中
if Qhcol == 0:
if Qhrow == 0: # 初始化全选复选框列表
self.QhCheckBoxList = []
self.QhCheckBoxList.append(Qhcheckbox) #以支持在列表头点击复选框时可全选行头的复选框 仅限于第一列
elif Qhtypestr=="QCOMBOBOX" :
#组合框控件
QhcomboBox = QComboBox()
QhitemobjName = "{}_{}_{}".format(Qhtypestr,Qhrow,Qhcol) # 按钮对象名称 记录按钮索引坐标
QhcomboBox.setObjectName(QhitemobjName)
self.QhitemData[Qhrow][Qhcol][4]=QhitemobjName # 需对绑定的数据重新赋值 数据对象名
Qhlst = self.getDicKeyValue(QhdicID)
self.setComboBoxItem(QhcomboBox,Qhlst)
Qhlayout.addWidget(QhcomboBox)
self.setCellWidget(Qhrow,Qhcol,Qhwidget)
QhcomboBox.setCurrentIndex(-1)
elif Qhtypestr=="QLABEL" :
# 自定义标签控件
Qhlabel = QLabelEx(self,Qhitemtext) #定义标签控件
QhitemobjName = "{}_{}_{}".format(Qhtypestr,Qhrow,Qhcol) # 按钮对象名称 记录按钮索引坐标
Qhlabel.setObjectName(QhitemobjName)
self.QhitemData[Qhrow][Qhcol][4]=QhitemobjName # 需对绑定的数据重新赋值 数据对象名
# Qhlayout.setContentsMargins(3, 3, 3, 3)
Qhlayout.addWidget(Qhlabel)
Qhlabel.signal_Leftclicked.connect(lambda state, Qhlabel=Qhlabel: self.label_clicked(Qhlabel))
self.setCellWidget(Qhrow,Qhcol,Qhwidget) # 连接信号槽:因原生标签没有单位信号,用继承标签类
elif Qhtypestr=="QPUSHBUTTON" :
# 按纽控件
# 按钮添加到表格的单元格中
Qhlayout.setContentsMargins(3, 3, 3, 3)
Qhitem = QTableWidgetItem()
if isinstance(Qhitemtext, list):
# 多个按钮
# ['QPUSHBUTTON',["执行","修改"],0,'0,0',['ZHIXING','XIUGAI'],None,None]
Qhitemtextl = ""
for Qhi,QhRow in enumerate(Qhitemtext):
QhitemtextRow = QhRow
if(Qhrow%2 == 0):
Qhbutton = QhQPushButton01(QhitemtextRow) # 创建按纽并设置文本
else:
Qhbutton = QhQPushButton02(QhitemtextRow) # 创建按纽并设置文本
QhitemobjNamels = copy.deepcopy(QhlstItemData[4][Qhi]) # 按钮class对象名称
QhitemobjName = "{}+{}_{}_{}".format(Qhtypestr,QhitemobjNamels,Qhrow,Qhcol) # 按钮对象名称 记录按钮索引坐标
Qhbutton.setObjectName(QhitemobjName)
self.QhitemData[Qhrow][Qhcol][4][Qhi]=QhitemobjName
Qhbutton.clicked.connect(lambda state, Qhbutton=Qhbutton: self.button_clicked(Qhbutton)) # 连接信号槽
Qhbutton.setMinimumSize(68, 22)
Qhlayout.addWidget(Qhbutton)
if Qhi == 0:
Qhitemtextl = QhitemtextRow
else:
Qhitemtextl = Qhitemtextl + "," + QhitemtextRow
Qhitem.setToolTip(Qhitemtextl)
else:
# 单个按钮
# ['QPUSHBUTTON',"执行",0,'0,0','ZHIXING',None,None]
if(Qhrow%2 == 0):
Qhbutton = QhQPushButton01(Qhitemtext) # 创建按纽并设置文本
else:
Qhbutton = QhQPushButton02(Qhitemtext) # 创建按纽并设置文本
QhitemobjNamels = copy.deepcopy(QhlstItemData[4]) # 按钮class对象名称
QhitemobjName = "{}+{}_{}_{}".format(Qhtypestr,QhitemobjNamels,Qhrow,Qhcol) # 按钮对象名称 记录按钮索引坐标
Qhbutton.setObjectName(QhitemobjName)
self.QhitemData[Qhrow][Qhcol][4]=QhitemobjName # 需对绑定的数据重新赋值 数据对象名
Qhbutton.clicked.connect(lambda state, Qhbutton=Qhbutton: self.button_clicked(Qhbutton)) # 连接信号槽
Qhbutton.setMinimumSize(68, 22)
Qhlayout.addWidget(Qhbutton)
Qhitem.setToolTip(Qhitemtext)
self.setCellWidget(Qhrow,Qhcol, Qhwidget) # 将按纽添加到表格的单元格中
else: #如控件有错,还是建立标准默认的单元格
Qhitem = QTableWidgetItem(Qhitemtext) #默认简化单行文本
self.setItem(Qhrow,Qhcol,Qhitem)
#标签控件槽函数
def label_clicked(self, label):
print(f'单击的标签控件: {label.text}')
#按纽控件槽函数
def button_clicked(self, button):
print(f'单击的按纽控件: {button.objectName()}')
# print(f'单击的按纽控件 坐标: {(button.objectName().split('_')[-2:])}')
def checkbox_clicked0(self, button):
# 单选方法
# 作者 : 阙辉
if button.isChecked():
button.setChecked(True)
else:
button.setChecked(False)
print(f'QhNEW单击的复合框控件: {button.objectName()}')
#复选按纽控件槽函数
def checkbox_clicked(self, button):
if self.QhCheckBoxflag:
col = 0
row = int(self.curRowCount)
self.QhSetCheckBoxQuanQuXiao(row,col)
button.setChecked(True)
# obj=self.findChild(QPushButton,str("pushButton_2"))
# obj.setText("全选中")
else:
print(button.isChecked())
if button.isChecked():
button.setChecked(True)
else:
button.setChecked(False)
print(f'单击的复合框控件: {button.objectName()}')
# print(f'单击的复合框控件 坐标: {(button.objectName().split('_')[-2:])}')
def QhclearCell(self, row, col):
# 冻结列 逻辑重写
# 清除单元格内容 阙辉
if(row>0 and row< (self.curRowCount-1) and col>0 and col< (self.curColCount-1)):
item = self.QhGetitem(row, col) # 清除指定行列的单元格内容
if(item is not None):
item.setText('') #非控件单元格不作移除,但要删除内容
self.QhitemData[row][col][1]='' #同时清除绑定的数据列表数据
self.QhitemData[row][col][0]='STR'
self.removeCellWidget(row,col) #移除原位置上的单元格控件
def QhAddAllRow(self,QhRow,QhRowItemData):
self.resizeRowToContents(QhRow)
for QhI,QhRow01 in enumerate(QhRowItemData):
QhItemDataone = copy.deepcopy(QhRow01)
self.QhsetItemData(QhRow,QhI,QhItemDataone)
#在表格末尾增加一行数据
def QhAppendItemRow(self,QhRowItemData):
# lstItems=self.getRowItems(self.curRowCount-1) #得到最后一行的数据
# self.insertRow(self.curRowCount)
self.QhitemData.append(copy.deepcopy(QhRowItemData))
self.curRowCount+=1
QhRow = self.curRowCount-1
self.insertRow(QhRow) #增加一行
self.QhAddAllRow(QhRow,QhRowItemData)
# self.itemData.append(copy.deepcopy(lstItems))
# self.setOneRowTableData(self.curRowCount-1) #刷新最后一行数据显示
def setComboBoxItem(self,comboObj,lstItem):
comboObj.clear()
for item in lstItem:
comboObj.addItem(item)
def QhSetCheckBoxQuanXuan(self,row,col):
for i in range(row):
# print(i)
QhObjName = self.QhitemData[i][col][4]
obj=self.findChild(QCheckBox,str(QhObjName))
obj.setChecked(True)
self.QhCheckBoxflag = True
def QhSetCheckBoxQuanQuXiao(self,row,col):
for i in range(row):
QhObjName = self.QhitemData[i][col][4]
obj=self.findChild(QCheckBox,str(QhObjName))
obj.setChecked(False)
self.QhCheckBoxflag = False
def QhSetCheckBoxTF(self):
print("QhSetCheckBoxTF")
col = 0
row = int(self.curRowCount)
print(row)
# for i in range(row):
# print(i)
# QhObjName = self.QhitemData[i][col][4]
# obj=self.findChild(QCheckBox,str(QhObjName))
# obj.setChecked(True)
if not self.QhCheckBoxflag:
self.QhSetCheckBoxQuanXuan(row,col)
# obj=self.findChild(QPushButton,str("pushButton_2"))
# print(obj)
# obj.setText("全取消")
else:
self.QhSetCheckBoxQuanQuXiao(row,col)
# obj=self.findChild(QPushButton,str("pushButton_2"))
# obj.setText("全选中")
def QhSelectCheckBoxTF(self):
# 全选和取消算法,瞬间响应,不需等待所有复选框都选中或取消
# 作者:阙辉
# 真 if 条件 else 假
print(len(self.QhCheckBoxList))
QhCheckBoxFList = [1 if QhRow.isChecked() else 0 for QhRow in self.QhCheckBoxList]
if 0 in QhCheckBoxFList:
[QhRow.setChecked(True) for QhRow in self.QhCheckBoxList]
else:
[QhRow.setChecked(False) for QhRow in self.QhCheckBoxList]
#自定义格式的编辑框控件,可用为自定义的表格单元格
class OwnQLineEdit(QLineEdit):
def __init__(self,parent,txtType='',font=QFont('宋体', 11),fcolor=QColor(0,0,0)):
super(QLineEdit, self).__init__(parent)
self.txtType=txtType.upper() #编辑框的文本类型:'INT'=整型 'FLOAT'=浮点数,'DATE'=日期,'TIME'=时间,'PASSWORD'=密码
self.setFrame(QFrame.NoFrame)
self.setEditMask(txtType)
#设置文本框的掩码类型
def setEditMask(self,txtType=''):
if(len(txtType)>0):
self.styleTxt=txtType
if(self.txtType=='INT'):
styleTxt='999999999999;#'
elif(self.txtType=='FLOAT'):
styleTxt='99999999.999'
elif(self.txtType=='DATE'):
styleTxt='9999-99-99'
elif(self.txtType=='TIME'):
styleTxt='99:99:99'
elif(self.txtType=='PASSWORD'):
self.setEchoMode(QLineEdit.Password)
return
else:
self.setInputMask(txtType)
#自定义格式的编辑框控件,可用为自定义的表格单元格
class OwnQTextEdit(QTextEdit):
def __init__(self,parent,txtType='',font=QFont('宋体', 11),fcolor=QColor(0,0,0)):
super(QTextEdit, self).__init__(parent)
self.txtType=txtType.upper() #编辑框的文本类型:'INT'=整型 'FLOAT'=浮点数,'DATE'=日期,'TIME'=时间,'PASSWORD'=密码
self.setFrameShape(QFrame.NoFrame)
#重载标签类,标签可透明显示图像,用于在窗体上加载小分部图像
lst_ImgExName=['BMP','JPG','JPEG','PNG','TIF','TIFF','TGA','WMF','SVG','HEIF','RAW','WEBP']
lst_MovExName=['GIF','AVI','MPEG','MP4','MOV','MKV','WMV','FLV','RMVB','RM','RAM']
lst_AlignType=['TL','TC','TR','CL','CC','CR','DL','DC','DR']
class QLabelEx(QLabel):
objcount=0 #
signal_Leftclicked = QtCore.pyqtSignal(object) #自定信号,标签被左键单击,传回参数:控件对象本身
signal_Rightclicked = QtCore.pyqtSignal(object) #自定信号,标签被右键单击,传回参数:控件对象本身
signal_Midclicked = QtCore.pyqtSignal(object) #自定信号,标签被中键单击,传回参数:控件对象本身
signal_LeftDropRelease = QtCore.pyqtSignal(object) #自定信号,标签被左键拖动后释放,传回参数:控件对象本身
#初始化对角需传递的参数为 父类,创建矩形,内容, 控件透明度 字体 字体颜色 背景颜色
def __init__(self,parent,text='',transt=1.0,font=QFont('宋体', 11),fcolor=QColor(0,0,0)):
super(QLabel, self).__init__(parent)
self.type='TXT' #标签控件的类型,'TXT'=纯文本标签,‘IMG'=可显示图片标签 'MOV':可播放动画标签
#self.setGeometry(x,y,w,h)
#self.ctlRect=QRect(x,y,w,h) #控件的矩形区域
self.imgRect=QRect() #如果控件加载了图象或视频自身尺寸的矩形区域
self.bDrawRect = False #是否在标签控件外边画出矩形框
self.rectCol=QColor(255,0,0) #画矩形边框的颜色
self.rectPenWidth=2 #画矩形边框的线宽度
self.bChgCtlRect=False #如果self.ctlRect不能满足文字、图象的矩形区域时,是否允许控件变化其矩形来适应文字或图象要求的矩形区域
self.move_Flag = False #标签控件是否可以主窗体上拖动:对窗体元素,应设置为False
self.bZoomImgSize=True #控件的矩形区同图象的矩形区不相符时,是否允许图象或视频自动缩放以适应控件矩形区
self.setScaledContents(self.bZoomImgSize) # 设置标签的图片,设置True时图片自适应控件,为False时,只显示控件范围图片
self.setAutoFillBackground(False) #不允许自动填充背景底色
self.text=text #标签是文本类型时显示的内容
self.drawText=text #标签是图片或视频类型时显示的内容
self.alignFlags=Qt.AlignTop | Qt.AlignLeft #对齐方式
self.bDrawTxt = False #显示图片的同时,是否将self.drawText画到图象上
self.fontCol=fcolor #字体颜色
self.bkCol=QColor(255,255,255) #如设置不透明时的标签背景颜色
self.setFont(font)
palette = QPalette()
palette.setColor(QPalette.WindowText, self.fontCol) #设置字体颜色
self.setPalette(palette)
self.SetTransparent(transt) #设置控件的透明度,1=不透明,0=完全透明
self.setText(text)
self.global_X=self.gobal_Y=0 #标签相对屏幕左上点(0,0)的坐标
self.startPoint=QPoint() #鼠标在标签控件上压下开始的坐标点
self.endPoint=QPoint() #鼠标在标签控件上压下结束时的坐标点
self.mouse_X=self.mouse_Y=0 #鼠标在标签控件上相对标签控件范围的坐标
self.origin_x=self.origin_y=0
self.globalmouse_X=self.globalmouse_Y=0 #鼠标在标签控件上相对屏幕左上点(0,0)的坐标
self.oldPos=QPoint() #移动前标签控件的位置
self.curImgfilename=''
self.curMovFileName=''
self.curData=None #当标签是加载的图片或动画时,将文件同容加载到内存中再显示,避免频繁读写文件
self.image=QImage()
self.curRotAngle=0.0 #图片当前旋转角度(角度,非弧度,顺时针为正)
self.gifSpeed=200 #当前要播放的GIF动画的速度
self.drawtxtX=self.drawtxtY=0
#如要要不透明的标签,设置标签背景色
def setBkCol(self,bkcol=QColor(255,255,255)):
self.bkCol=bkcol
palette = QPalette()
self.setAutoFillBackground(True)
palette.setColor(QPalette.Background, self.bkCol)
self.setPalette(palette)
#设置标签中的文字/图片/GIF动画对齐方式Qt.AlignLeft:左对齐Qt.AlignRight:右对齐 Qt.AlignTop:顶部对齐Qt.AlignBottom:底部对齐Qt.AlignHCenter:水平居中Qt.AlignVCenter:垂直居中Qt.AlignCenter:同时水平和垂直居中
def SetAlign(self,at='TL'): #
at=at.upper()
self.alignFlags=Qt.AlignTop | Qt.AlignLeft
if(at=='TL'): self.alignFlags=Qt.AlignTop | Qt.AlignLeft
elif(at=='TC'): self.alignFlags=Qt.AlignTop | Qt.AlignHCenter
elif(at=='TR'): self.alignFlags=Qt.AlignTop | Qt.AlignRight
elif(at=='CL'): self.alignFlags=Qt.AlignVCenter | Qt.AlignLeft
elif(at=='CC'): self.alignFlags=Qt.AlignVCenter | Qt.AlignHCenter
elif(at=='CR'): self.alignFlags=Qt.AlignVCenter | Qt.AlignRight
elif(at=='DL'): self.alignFlags=Qt.AlignBottom | Qt.AlignLeft
elif(at=='DC'): self.alignFlags=Qt.AlignBottom | Qt.AlignHCenter
elif(at=='DR'): self.alignFlags=Qt.AlignBottom | Qt.AlignRight
else:self.alignFlags=Qt.AlignVCenter | Qt.AlignLeft
self.setAlignment(self.alignFlags)
self.setText(self.text) #有时并没有出现对齐效果,只能采用先清除再重加载的方式
#旋转控件中的图片一指定的角度:角度为正东向,向顺时针旋转的角度为正,反之为负(非弧度)
def RotateImg(self,angle):
if(self.type=='IMG' and self.curData!=None):
transform = QTransform()
transform.rotate(angle)
self.image=self.image.transformed(transform);
self.setPixmap(QPixmap.fromImage(self.image)) # 显示图片到Qlabel控件
if(self.bChgCtlRect): #为真时,旋转后同时调整控件大小
self.resize(self.image.width(),self.image.height())
#设置标签控件在加载图片时,控件尺寸同图片尺寸不符时,是否允许控件调整自身的矩形区域,以适应1:1的图象显示
def ObjToImgSize(self):
self.setScaledContents(self.bZoomImgSize) #不允许自适应控件,只1:1显示到控件中,同时调整控件大小
if(self.bChgCtlRect): #只有先设置此属性为真时,才允许变化控件尺寸
if(self.curData!=None):
image= QImage.fromData(self.curData)
self.resize(image.width(),image.height()) #用下行后用设置参数中的矩形,用本行就是图片本身的尺寸
self.ctlRect=QRect(self.x(),self.y(),self.width(),self.height())
#设置标签加载的文件名称,可以是图片也可以是动画GIF或视频
def LoadFile(self,filename=''):
if(os.path.exists(filename)):
file_extension = str(filename.split(".")[-1]).upper()
bOK=False
for exname in lst_ImgExName:
if file_extension == exname:
self.type='IMG'
bOK=True
break
for exname in lst_MovExName:
if file_extension == exname:
self.type='MOV'
bOK=True
break
if (bOK):
with open(filename, 'rb') as f:
self.curData = f.read()
self.image= QImage.fromData(self.curData)
self.curMovFileName=filename
self.RefreshLable()
else:
print(f'没有找到对应扩展名: {file_extension} 的分类')
self.type='TXT'
self.ReshowText(self.text)
self.ObjToImgSize()
else:
self.type='TXT'
self.ReshowText(self.text)
#清除图象,重新显示标签的文本
def ReshowText(self,txt):
self.text=txt
self.clear()
self.type='TXT'
self.setText(txt)
#设置显示图片的同时,画到标签控件上的文本,传入文本为空时,同标签控件初始化时的字符串一致,图形模式下,不调用此函数,默认不会绘出文本
def setDrawText(self,txt,x=0,y=0):
self.bDrawTxt=True
if(len(txt)==0):
self.drawText=self.text
else:
self.drawText=txt
self.drawtxtX=x
self.drawtxtY=y
#重新显示标签(在用了LoadFile后)
def RefreshLable(self): #如果图片被调整乱了,且不想要控件尺寸同图片尺寸
self.setScaledContents(self.bZoomImgSize) #不允许自适应控件,只1:1显示到控件中,同时调整控件大小
if(self.type=='IMG'):
self.image= QImage.fromData(self.curData)
self.setPixmap(QPixmap.fromImage(self.image)) # 显示图片到Qlabel控件
self.imgRect=QRect(self.x(),self.y(),self.image.width(),self.image.height())
if(self.bChgCtlRect):
self.resize(self.image.width(),self.image.height()) #用下行后用设置参数中的矩形,用本行就是图片本身的尺寸
elif(self.type=='MOV'):
self.movie = QMovie(self.curMovFileName)
# 将movie应用到label上
self.setMovie(self.movie)
self.total_frame = self.movie.frameCount()
self.gifSpeed=self.movie.speed()
#print(f'当前GIF文件=’{self.curMovFileName}‘,总帧数={self.total_frame},默认正常播放速度={self.gifSpeed}')
self.set_GifSpeed(self.gifSpeed) #设置播放动画GIF的整速度:方法接受的是每1000毫秒播放的帧数比例,如是1:表示,一秒显示全部帧数,0.5表示一秒显示半数的帧数。
self.movie.start()
#"""
else: #self.type=='TXT'
pass
#设置播放GIF动画的速度: interval值哦本准备播放GIF的默认播放速度的倍数,如当前GIF默认播放速度为100
def set_GifSpeed(self,interval=100.0):
self.gifSpeed=interval
if(self.type=='MOV' and self.movie!=None):
self.movie.setSpeed(interval) # 设置播放速度
#设置标签控件的透明程度:对文字及图片均有效
def SetTransparent(self,trans):
if trans>1:trans=1
elif trans<0:trans=0
self.Transparent=trans
opacity_effect = QGraphicsOpacityEffect(parent=self)
opacity_effect.setOpacity(trans) # 设置透明度
self.setGraphicsEffect(opacity_effect) # 将透明度效果应用到标签上
#self.setWindowOpacity(self.Transparent)
#设置本标签对象是在最上方还是在最下方
def setLabelLayer(self,bTop=True):
if(bTop):self.raise_()
else:self.lower()
#设置标签显示的文本的字体
def setTextFont(self,fontname='宋体',fontsize=11,bBold=False,bItalic=False,bUnderline=False):
font = QFont()
font.setFamily(fontname) # 设置字体名称
font.setPointSize(fontsize) # 设置字体大小
font.setBold(bBold) # 设置字体加粗
font.setItalic(False)
font.setUnderline(False)
self.setFont(font)
#设置标签显示的文本的字体
def setTextCol(self,fcol=QColor(0,0,0)):
self.setStyleSheet(f"QLabel {{ color: {fcol.name()}; }}")
#设置标签显示的文本的字体
def setTextBkCol(self,bkcol=QColor(255,255,255)):
if( not self.bTransparent): #对非透明模式才支持设置标签背景颜色
self.setAutoFillBackground(True) # 确保背景自动填充
palette = self.palette()
palette.setColor(QPalette.Window, bkcol)
self.setPalette(palette)
#得到标签矩形中心位置
def getObjRect(self):
size = self.geometry()
self.centerX=size.x()+size.width()/2
self.centerY=size.y()+size.height()/2
return size.x(),size.y(),size.width(),size.height()
#鼠标按下事件重载
def mousePressEvent(self, event):
self.startPoint=event.pos()
self.oldPos=QPoint(event.globalX(),event.globalY())
# 核心部分: 当鼠标点击是左键 并且 在top控件内点击时候触发
if (event.button() == Qt.LeftButton and self.move_Flag): #and self.top.underMouse():
self.setCursor(Qt.OpenHandCursor) #移动时设置成手型光标
# 但判断条件满足时候, 把拖动标识位设定为真
#self.move_Flag = True
self.globalmouse_X = event.globalX()
self.globalmouse_Y = event.globalY()
# 获取窗体当前坐标
self.origin_x = self.x()
self.origin_y = self.y()
#鼠标移动事件重载
def mouseMoveEvent(self, event):
# 拖动标识位设定为真时, 进入移动事件
if self.move_Flag:
# 计算鼠标移动的x,y位移
move_x = event.globalX() - self.globalmouse_X
move_y = event.globalY() - self.globalmouse_Y
# 计算窗体更新后的坐标:更新后的坐标 = 原本的坐标 + 鼠标的位移
dest_x = self.origin_x + move_x
dest_y = self.origin_y + move_y
# 移动本标签控件
size = self.geometry()
self.move(dest_x, dest_y)
self.ctlRect=QRect(self.x(),self.y(),self.width(),self.height())
self.setLabelLayer(True) #拖动的标签控件角色在最顶端显示
# 鼠标左键释放
def mouseReleaseEvent(self, event):
self.endPoint=event.pos()
newPos=QPoint(event.globalX(),event.globalY())
if (event.button() == Qt.LeftButton and self.move_Flag):
self.setCursor(Qt.ArrowCursor) # 设定鼠标为普通状态: 箭头
if(self.move_Flag==False): #非对象拖动状态,鼠标在控件区域移动一位置
if(abs(self.endPoint.x()-self.startPoint.x())<2 and abs(self.endPoint.y()-self.startPoint.y())<2 ): #判断是否单击
if(event.button() == Qt.LeftButton):
print('非拖动状态下:是左键单击不是拖动')
self.signal_Leftclicked.emit(self)
elif(event.button() == Qt.RightButton):
print('非拖动状态下:是右键单击不是拖动')
self.signal_Rightclicked.emit(self)
elif(event.button() == Qt.MidButton):
print('非拖动状态下:是中键单击不是拖动')
self.signal_Midclicked.emit(self)
else:
print('非拖动状态下,鼠标在控件上移动了一位置')
else: #拖动对象状态,除非一点也没拖动,否则不对单位处理
if(abs(self.oldPos.x()-newPos.x())<2 and abs(self.oldPos.y()-newPos.y())<2 ):
print('虽是拖动状态但是并没拖动对象')
if(event.button() == Qt.LeftButton):
print('拖动状态下:是左键单击不是拖动')
self.signal_Leftclicked.emit(self)
elif(event.button() == Qt.RightButton):
print('拖动状态下:是右键单击不是拖动')
self.signal_Rightclicked.emit(self)
elif(event.button() == Qt.MidButton):
print('拖动状态下:是中键单击不是拖动')
self.signal_Midclicked.emit(self)
else: #拖动对象移动了位置
print('拖动状态下:左键拖动控件移动了位置')
self.signal_LeftDropRelease.emit(self)
#重载绘图函数:
def paintEvent(self, event):
if (self.bDrawRect): #标签控件是否绘制边框架
self.DrawObjRect(self.rectCol,self.rectPenWidth) #为控件画出外边框
if(self.bDrawTxt): #是否在标签控件上画出文本
pen = QPen() # 创建画笔对象
painter = QPainter(self) # 此QPainter只能在paintEvent中定义,不能定义成类的self成员对象,也不能在其地方(如其他窗口,线程中)定义,否则没有绘画功能显示
#绘制
pen.setColor(self.fontCol)
painter.drawText(self.drawtxtX,self.drawtxtY,self.width(),self.height(),self.alignFlags,self.drawText)
return super().paintEvent(event) #调用主窗口的重绘事件,不用不会加载动画只显示第一帖,用了动画加载正常,但又多了一静态图第一帖
#画出当前控件的矩形框(用于对象被选择时)
def DrawObjRect(self,pencol,penwidth):
self.rectCol=pencol
self.rectPenWidth=penwidth
if(self.bDrawRect):
pen = QPen() # 创建画笔对象
brush = QBrush() # 创建画刷对象
painter = QPainter(self) # 此QPainter只能在paintEvent中定义,不能定义成类的self成员对象,也不能在其地方(如其他窗口,线程中)定义,否则没有绘画功能显示
#绘制
pen.setColor(pencol)
pen.setStyle(Qt.SolidLine)
pen.setWidth(penwidth) # 设置画笔宽度
painter.setPen(pen) # 设置画笔
self.pixmap = QPixmap.fromImage(self.image)
#painter.drawPixmap(0, 0, self.pixmap)
painter.drawRect(0,0,self.width(),self.height())
class QhQPushButton01(QPushButton):
def __init__(self,parent):
super(QPushButton, self).__init__(parent)
class QhQPushButton02(QPushButton):
def __init__(self,parent):
super(QPushButton, self).__init__(parent)