import sys,os,zipfile
import numpy as np
import pandas as pd
from PyQt5.QtWidgets import QApplication,QWidget,QMainWindow,QVBoxLayout,QLabel,QLineEdit,QFormLayout,\
QTableWidget,QDesktopWidget,QHBoxLayout,QPushButton,QFileDialog,QTextEdit,QMenu,QComboBox,QMessageBox
from PyQt5.QtGui import QFont,QIcon
from PyQt5.QtCore import Qt
def zip_folder(folder_path, output_path):
'''
:param folder_path: 需要打包的文件夹路径
:param output_path: 打包完成后的压缩包放置的路径,如:D:/我的文档/Desktop/毛泽东.zip
:return:
'''
# 创建一个 ZipFile 对象
with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
# 遍历文件夹中的所有文件和子文件夹
for root, dirs, files in os.walk(folder_path):
for file in files:
# 获取文件的完整路径
file_path = os.path.join(root, file)
# 将文件添加到压缩包中,使用相对路径
zipf.write(file_path, os.path.relpath(file_path, folder_path))
class myWin(QMainWindow):
def __init__(self):
super(myWin, self).__init__()
self.setWindowTitle('付款管理系统')
# 设置窗口尺寸为电脑屏幕尺寸
desktop = QDesktopWidget()
screen_width = desktop.screenGeometry().width()
screen_height = desktop.screenGeometry().height()
self.resize(int(screen_width/2),int(screen_height/2))
self.setMenu()
# 文件路径
# 1.项目文件(压缩包)保存路径
self.SaveProjectZipFilePath = None
# 2.项目文件(压缩包)打开路径
self.OpenProjcetZipFilePath=None
# 3.文件另存为路径
self.SaveAsProjectZipFilePath=None
# 4.当前运行文件所在的文件夹
self.ProjectRunPath=None
if getattr(sys,'frozen',False):
self.ProjectRunPath=os.path.dirname(sys.executable)
else:
self.ProjectRunPath=os.path.dirname(os.path.abspath(__file__))
# 5.数据临时存放的文件夹
self.provisionalSavePath=os.path.join(self.ProjectRunPath,'项目运行文件夹')
# print(self.provisionalSavePath)
if os.path.exists(self.provisionalSavePath):
pass
else:
os.mkdir(self.provisionalSavePath)
# 设置标题栏Icon
icon_path=os.path.join(self.ProjectRunPath, 'icon.jpg')
self.setWindowIcon(QIcon(icon_path))
'''
os.path.dirname() 表示某个路径的上一级目录。
os.path.join() 拼接路径
pyinstaller 打包配置文件时,所有的配置文件,运行时所有的配置文件必须和exe文件所在同一个文件夹中
'''
def setMenu(self):
self.bar=self.menuBar()
self.bar.setFont(QFont('楷书',14))
# 文件菜单
file=self.bar.addMenu('文件')
file.setFont(QFont('楷书',12))
f1=file.addAction('新建ToDo')
f1.triggered.connect(self.CreatProject)
f2=file.addAction('打开')
f2.triggered.connect(self.OpenProject)
f3=file.addAction('保存')
f3.triggered.connect(self.SaveProject)
f4=file.addAction('另存为')
'''
点击取消时,程序崩溃,提示:Qt: Untested Windows version 10.0 detected!
'''
f4.triggered.connect(self.SaveAsProject)
f5=file.addAction('打印')
f6=file.addAction('选项')
f6.triggered.connect(self.setOption)
set=self.bar.addMenu('付款设置')
set.setFont(QFont('楷书',12))
s1=set.addAction('项目信息')
s1.triggered.connect(self.setProject)
'''
1.项目名称
2.保存路径
3.工程总量指标及楼层/分区工程量指标
'''
set.addAction('清单与总价')
payment=self.bar.addMenu('支付管理')
payment.setFont(QFont('楷书',12))
p1=payment.addAction('添加分包')
p1.triggered.connect(self.AddTeamUI)
payment.addAction('分包付款申请')
payment.addAction('项目累计付款')
payment.addAction('分包累计付款')
payment.addAction('付款资料管理')
report=self.bar.addMenu('报表')
report.setFont(QFont('楷书', 12))
report.addAction('导出excel')
report.addAction('加密并导出excel')
report.addAction('解密excel文件')
ToolBox=self.bar.addMenu('工具箱')
ToolBox.setFont(QFont('楷书', 12))
ToolBox.addAction('图片格式转换')
ToolBox.addAction('图片一键水印')
def CreatProject(self):
print('拟采用登录后弹出新窗口的方法创建此功能!')
pass
'''
打算使用进入登录窗口后,弹出新的界面,该界面包括现有的打开、保存、另存为等文件夹中的功能。
'''
def OpenProject(self):
self.OpenProjcetZipFilePath, _ = QFileDialog.getOpenFileName(self, '打开文件', '', 'zip文件(*.zip)')
with zipfile.ZipFile(file=self.OpenProjcetZipFilePath, mode='r') as z:
z.extractall(path=self.provisionalSavePath)
print(self.provisionalSavePath)
def SaveProject(self):#“文件/保存”功能
if (self.SaveProjectZipFilePath is None) and (self.OpenProjcetZipFilePath is None):
file_dialog = QFileDialog()
file_dialog.setFileMode(QFileDialog.AnyFile)
file_dialog.setNameFilter("压缩文件(*.zip)")
file_dialog.setAcceptMode(QFileDialog.AcceptSave)
if file_dialog.exec_() == QFileDialog.Accepted:
self.SaveProjectZipFilePath = file_dialog.selectedFiles()[0]
zip_folder(self.provisionalSavePath, self.SaveProjectZipFilePath)
elif (self.SaveProjectZipFilePath is None) and (self.OpenProjcetZipFilePath is not None):
self.SaveProjectZipFilePath = self.OpenProjcetZipFilePath
zip_folder(self.provisionalSavePath, self.SaveProjectZipFilePath)
elif (self.SaveProjectZipFilePath is not None) and (self.OpenProjcetZipFilePath is None):
zip_folder(self.provisionalSavePath, self.SaveProjectZipFilePath)
elif (self.SaveProjectZipFilePath is not None) and (self.OpenProjcetZipFilePath is not None):
zip_folder(self.provisionalSavePath, self.SaveProjectZipFilePath)
def SaveAsProject(self):#“文件/另存为功能”
file_dialog = QFileDialog()
file_dialog.setFileMode(QFileDialog.AnyFile)
file_dialog.setNameFilter("压缩文件(*.zip)")
file_dialog.setAcceptMode(QFileDialog.AcceptSave)
if file_dialog.exec_() == QFileDialog.Accepted:
self.SaveProjectZipFilePath = file_dialog.selectedFiles()[0]
self.SaveProject()
print(f'另存为路径:{self.SaveProjectZipFilePath}')
'''
原因不需要每次都弹出另存为对话框,只需要将弹出的保存对话框中的路径,赋值给保存路径SaveProjectZipFilePath即可,同
时也不需要单独再定义一个另存为路径变量SaveAsProjectZipFilePath
'''
def closeEvent(self, event):
result = QMessageBox.question(self, '提示', '是否保存文件?',QMessageBox.Yes | QMessageBox.No)
# 根据返回值处理用户的选择
if result == QMessageBox.Yes:
self.SaveProject()
elif result == QMessageBox.No:
pass
# print("用户点击了'否'")
# self.SaveProject()
# 在这里处理窗口关闭前的逻辑
# print("窗口即将关闭")
# 如果需要阻止关闭,可以调用 event.ignore()
# 如果处理完毕,调用 event.accept() 来接受关闭事件
event.accept()
'''
关闭窗口时,清除临时文件,该功能未实现,因为os.remove()函数用不了,受windows系统文件访问权限的限制,本次使用的功
能,是zipfile库中,打开文件时,解压新的压缩包,覆盖掉原来的临时文件中的所有文件。
'''
def setOption(self):
self.setOption_QWidget=QWidget()
self.setOption_QWidget.setWindowTitle('选项')
self.setOption_QWidget.resize(int(self.size().width() / 3), int(self.size().height() / 3))
setOption_mainLay=QVBoxLayout()
self.setOption_QWidget.setLayout(setOption_mainLay)
setOption_HLay1=QHBoxLayout()
setOption_mainLay.addLayout(setOption_HLay1)
setOption_label1=QLabel('默认路径')
self.setOption_lineEdit1=QLineEdit()
self.setOption_lineEdit1.setText(self.ProjectRunPath)
setOption_path_pushButton=QPushButton('选择')
# todo "选择"按钮的功能有待开发,不但可以更改默认路径,而且应将项目文件剪切至修改后的路径
setOption_HLay1.addWidget(setOption_label1)
setOption_HLay1.addWidget(self.setOption_lineEdit1)
setOption_HLay1.addWidget(setOption_path_pushButton)
setOption_formLay=QFormLayout()
setOption_mainLay.addLayout(setOption_formLay)
setOption_label2=QLabel('有待开发')
self.setOption_lineEdit2=QLineEdit()
setOption_formLay.addRow(setOption_label2, self.setOption_lineEdit2)
setOption_mainLay.addStretch()
setOption_HLay2=QHBoxLayout()
setOption_mainLay.addLayout(setOption_HLay2)
setOption_HLay2.addStretch()
setOption_pushButton1=QPushButton('确定')
setOption_pushButton2 = QPushButton('取消')
setOption_HLay2.addWidget(setOption_pushButton1)
setOption_HLay2.addWidget(setOption_pushButton2)
self.setOption_QWidget.show()
def setProject(self):
self.Project_QWidget=QWidget()
self.Project_QWidget.setWindowTitle('项目设置')
self.Project_QWidget.resize(int(self.size().width() / 3), int(self.size().height() / 3))
Project_QWidget_MainLay=QVBoxLayout()
self.Project_QWidget.setLayout(Project_QWidget_MainLay)
FormLay=QFormLayout()
Project_QWidget_MainLay.addLayout(FormLay)
self.setProject_label1=QLabel('项目名称')
self.setProject_lineEdit1=QLineEdit()
FormLay.addRow(self.setProject_label1,self.setProject_lineEdit1)
# formLay.addRow(label1,self.lineEdit1)
self.setProject_label2=QLabel('结构类型')
self.setProject_lineEdit2=QLineEdit()
FormLay.addRow(self.setProject_label2,self.setProject_lineEdit2)
self.setProject_label3=QLabel('建筑面积')
self.setProject_lineEdit3=QLineEdit()
FormLay.addRow(self.setProject_label3,self.setProject_lineEdit3)
self.setProject_label4=QLabel('付款方式')
self.setProject_lineEdit4=QLineEdit()
FormLay.addRow(self.setProject_label4,self.setProject_lineEdit4)
self.setProject_label5=QLabel('项目负责人')
self.setProject_lineEdit5=QLineEdit()
FormLay.addRow(self.setProject_label5,self.setProject_lineEdit5)
self.setProject_label6=QLabel('项目地址')
self.setProject_lineEdit6=QLineEdit()
FormLay.addRow(self.setProject_label6,self.setProject_lineEdit6)
Project_QWidget_VLay=QHBoxLayout()
Project_QWidget_MainLay.addLayout(Project_QWidget_VLay)
self.setProject_label7=QLabel('文件路径')
self.setProject_lineEdit7=QLineEdit()
self.setProject_pushButton=QPushButton('设置')
self.setProject_pushButton.clicked.connect(self.setFileSavePath)
Project_QWidget_VLay.addWidget(self.setProject_label7)
Project_QWidget_VLay.addWidget(self.setProject_lineEdit7)
Project_QWidget_VLay.addWidget(self.setProject_pushButton)
Project_QWidget_MainLay.addStretch()
self.Project_QWidget.show()
def setFileSavePath(self):
file_save_path=QFileDialog.getExistingDirectory()
self.setProject_lineEdit7.setText(file_save_path)
print(file_save_path)
def AddTeamUI(self):
self.Team_QWidget=QWidget()
self.Team_QWidget.setWindowTitle('添加分包信息')
self.Team_QWidget.resize(int(self.size().width() / 2), int(self.size().height() / 2))
# 1.设置主布局
mainLay=QVBoxLayout()
self.Team_QWidget.setLayout(mainLay)
# 2.设置菜单布局
formLay=QFormLayout()
mainLay.addLayout(formLay)
label1=QLabel('分包单位')
self.lineEdit1=QLineEdit()
formLay.addRow(label1,self.lineEdit1)
# TODO 将分包单位设置成QComBox对象,读取已有的分包单位并设置在下拉框中,并且允许用户编辑内容,将默认显示文
# 本设置不空,并将该文字设置为控件提示内容
info_save_path=os.path.join(self.provisionalSavePath,'支付管理','分包单位信息.csv')
if os.path.exists(info_save_path):
pass
else:
pass
main_service_label=QLabel('主要服务')
self.main_service_lineEdit=QLineEdit()
formLay.addRow(main_service_label,self.main_service_lineEdit)
major_label=QLabel('专业类别')
self.major_lineEdit=QLineEdit()
formLay.addRow(major_label,self.major_lineEdit)
cost_sort_label=QLabel('费用类别')
self.cost_sort_lineEdit=QLineEdit()
formLay.addRow(cost_sort_label,self.cost_sort_lineEdit)
label2=QLabel('项目负责人')
self.lineEdit2=QLineEdit()
formLay.addRow(label2,self.lineEdit2)
label3=QLabel('联系电话')
self.lineEdit3=QLineEdit()
formLay.addRow(label3,self.lineEdit3)
'''
添加标签为了后续统计使用
专业:土建、机电、安装、精装等
费用类别:人工、机械、材料、其他
按年按季度统计
'''
# 3.设置合同单价等信息
self.team_table=QTableWidget()
mainLay.addWidget(self.team_table)
self.team_table.resize(self.Team_QWidget.size().width(), 300)
# 行数和列数
self.team_table.setRowCount(6)
self.team_table.setColumnCount(8)
# 设置列头并隐藏行头
self.team_table.setHorizontalHeaderLabels(['序号','工作名称','项目特征','单位','工程量','单价','合价','备注'])
self.team_table.verticalHeader().setVisible(False)
self.team_table.setStyleSheet("QTableWidget::item{border:0.5px groove #FF00FF}")
'''
好好研究一下如何为单元格加边框,资料来源:https://www.jb51.net/article/207822.htm
'''
# 设置行高和列宽
self.team_table.setRowHeight(1,200)
# 设置上下文菜单(即右键菜单)
self.team_table.setContextMenuPolicy(Qt.CustomContextMenu)
self.team_table.customContextMenuRequested.connect(self.Right)
self.right_menu=QMenu(self)
r1=self.right_menu.addAction('添加行')
r2=self.right_menu.addAction('删除行')
r3=self.right_menu.addAction('复制行')
r4=self.right_menu.addAction('粘贴行')
# 在项目特征列添加TextEdit控件实现换行输入,添加QComBox控件可以下拉选择单位并允许手动输入
for row_num in range(self.team_table.rowCount()):
textEdit=QTextEdit()
self.team_table.setCellWidget(row_num,2,textEdit)
combox=QComboBox()
combox.setEditable(True) # 允许QComBox添加新的内容
combox.addItems(['m','㎡','m³','t','kg','个','套','项'])
combox.setCurrentIndex(-1)
self.team_table.setCellWidget(row_num,3,combox)
# 4.设置水平布局并添加“确定”和“取消”按钮
hlay=QHBoxLayout()
mainLay.addLayout(hlay)
btn1=QPushButton('确定')
btn1.clicked.connect(self.Team_AddInfo)
btn2=QPushButton('取消')
hlay.addStretch()
hlay.addWidget(btn1)
hlay.addWidget(btn2)
self.Team_QWidget.show()
'''
在主窗口中显示子窗口的资料来源:
https://blog.csdn.net/qq_28077617/article/details/119608299
'''
def Right(self,point):
self.right_menu.exec_(self.team_table.mapToGlobal(point))
def Team_AddInfo(self):
# 设置文件路径
info_save_path=os.path.join(self.provisionalSavePath,'支付管理','分包单位信息.csv')
if os.path.exists(os.path.dirname(info_save_path)):
pass
else:
os.mkdir(os.path.dirname(info_save_path))
# 1.输出分包信息
# 添加分包信息
add_info_data=[{
'分包单位':self.lineEdit1.text(),
'项目负责人':self.lineEdit2.text(),
'联系电话':self.lineEdit3.text()
}]
add_info_df=pd.DataFrame(add_info_data)
# 读取分包信息
if os.path.exists(info_save_path):
print(True)
info_df=pd.read_csv(info_save_path)
drop_list=[]
for i in info_df.columns:
if i not in ['分包单位','项目负责人','联系电话']:
drop_list.append(i)
info_df.drop(columns=drop_list,inplace=True)
print(info_df)
else:
info_df=pd.DataFrame()
print(False)
# 添加分包信息警示对话框
if (self.lineEdit1.text()=='') or (self.lineEdit2.text()=='') or (self.lineEdit3.text()==''):
QMessageBox.warning(self.Team_QWidget,'警告','分包信息不完整,请补充完整!')
# 合并数据
info_df=pd.concat([info_df,add_info_df])
# 保存数据
info_df.to_csv(info_save_path,encoding='utf_8_sig')
# 2.输出单价信息
price_save_path=os.path.join(self.provisionalSavePath,'支付管理','合同清单价格.csv')
if os.path.exists(os.path.dirname(price_save_path)):
pass
else:
os.mkdir(os.path.dirname(price_save_path))
# 读取分包信息
if os.path.exists(price_save_path):
print(True)
price_df=pd.read_csv(price_save_path)
price_drop_list=[]
for i in price_df.columns:
if i not in ['序号','工作名称','项目特征','单位','工程量','单价','合价','备注']:
price_drop_list.append(i)
price_df.drop(columns=price_drop_list,inplace=True)
print(price_df)
else:
price_df=pd.DataFrame()
pass
price_df_add=pd.DataFrame(data='',index=range(self.team_table.rowCount()),columns=['序号','工作名称','项目特征','单位','工程量','单价','合价','备注'])
for row_num in range(self.team_table.rowCount()):
for col_num in range(self.team_table.columnCount()):
if col_num==2:
item_textEdit=self.team_table.cellWidget(row_num,col_num)
item_textEdit_text=item_textEdit.toPlainText()
if item_textEdit_text=='':
price_df_add.iloc[row_num, col_num]=np.NaN
else:
price_df_add.iloc[row_num, col_num]=item_textEdit_text
elif col_num==3:
item_comBox=self.team_table.cellWidget(row_num,col_num)
comBox_text=item_comBox.currentText()
if comBox_text=='':
price_df_add.iloc[row_num, col_num] =np.NaN
else:
price_df_add.iloc[row_num, col_num] = comBox_text
else:
item = self.team_table.item(row_num, col_num)
if item is not None:
price_df_add.iloc[row_num, col_num] = item.text()
else:
price_df_add.iloc[row_num, col_num] =np.NaN
print(price_df_add)
price_df_add.dropna(axis='index',subset=['序号','工作名称','项目特征','单位','工程量','单价','合价'],inplace=True) # 指定列有空值删除行
# 合并数据
price_df=pd.concat([price_df,price_df_add])
# 保存数据
price_df.to_csv(price_save_path,encoding='utf_8_sig')
# 判断合同清单项输入是否完整并弹出警告信息
for row_num in range(self.team_table.rowCount()):
table_warning_bool_list = []
for col_num in range(self.team_table.columnCount()-1):
if col_num==2:
item_textEdit=self.team_table.cellWidget(row_num,col_num)
item_textEdit_text=item_textEdit.toPlainText()
if item_textEdit_text=='':
table_warning_bool_list.append(False)
else:
table_warning_bool_list.append(True)
elif col_num==3:
item_comBox=self.team_table.cellWidget(row_num,col_num)
comBox_text=item_comBox.currentText()
if comBox_text=='':
table_warning_bool_list.append(False)
else:
table_warning_bool_list.append(True)
else:
item = self.team_table.item(row_num, col_num)
if item is not None:
table_warning_bool_list.append(True)
else:
table_warning_bool_list.append(False)
if (True in table_warning_bool_list) and (False in table_warning_bool_list):
table_warning=QMessageBox.warning(self.team_table,'警告',f'第{row_num}行清单信息输入不完整,请补充完整!')
'''
添加一列班组。
'''
if __name__ == '__main__':
app=QApplication(sys.argv)
w=myWin()
w.show()
app.exec()
'''
项目开发遇到的困难:
1.打包时,无法加载资源文件,比如图片,文本文档之类的文件。
2.在主窗口中嵌套子窗口
3.构造一个数据为一个字符的df
4.添加QComBox控件可以下拉选择单位并允许手动输入
5.实现第一保存弹出保存对话框,再次保存时,直接保存在次选择的路径
6.
100.研究一下添加右键菜单的方法
资料来源:https://www.jb51.net/article/167887.htm
101.单元格右下角填充功能,待研究,可参考资料:https://blog.csdn.net/weixin_56684324/article/details/129424336
参考资料:https://blog.csdn.net/mahongquan/article/details/139364986
代码如果运行,则需要稍做修改:
修改后的代码如下:
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5 import QtWidgets
import logging
from PyQt5 import QtCore
class MyTableWidget(QTableWidget):
dragbottom = pyqtSignal(object)
def __init__(self, parent):
super().__init__(parent)
self.cellBottomRight = False
self.leftbuttonDown = False
def paintEvent(self, e):
super().paintEvent(e)
painter = QPainter(self.viewport())
# painter.save();
pen = painter.pen();
pen.setWidth(1);
selections = self.selectionModel()
if selections != None:
# logging.info("not None")
list1 = selections.selectedIndexes()
for i in range(len(list1)):
modelIndex = list1[i]
# QRect类提供各种矩形坐标,绘制线跟点的时候需要用到坐标
rect = self.visualRect(modelIndex);
tmpRect = QtCore.QRect(QtCore.QPoint(rect.x() + 1, rect.y() + 1),
QtCore.QSize(rect.width() - 2, rect.height() - 2))
# 如果是选中状态 并且在选择公式状态
# if (self.item(i,j).isSelected()):
# 给选中单元格进行画线画点
dashes = []
penXu = painter.pen();
# 设置画笔宽度
penXu.setWidth(2);
color = QColor();
# 设置画笔颜色
color.setRgb(31, 187, 125);
penXu.setColor(color);
painter.setPen(penXu);
# 绘制单元格四周的线
painter.drawRect(tmpRect);
# 绘制单元格右下角点
penXu.setWidth(6);
painter.setPen(penXu);
painter.drawPoint(tmpRect.x() + tmpRect.width() - 3, tmpRect.y() + tmpRect.height() - 3);
# 恢复QPainter对象
# painter.restore();
# self.viewport().update();
# 鼠标移动事件
def mouseMoveEvent(self, event):
# 获取鼠标位置信息
if not self.cellBottomRight:
mousePos = event.pos();
# 获取所有选中单元格
# logging.info(self.cellBottomRight)
itemList = self.selectedItems();
# 没有选中单元格 就退出
if len(itemList) <= 0:
return;
modelIndex = self.indexFromItem(itemList[len(itemList) - 1]);
# 获取最后一个选中的单元格的QRect,用来判断是否鼠标位置是否在右下角区域
rect = self.visualRect(modelIndex);
# logging.info([mousePos,rect])
# 判断是否在我们规定的区域,或者是按下模式,isClick是按下模式标志
# print(dir(mousePos))
if ((mousePos.x() >= (rect.x() + rect.width() - 7) and mousePos.x() <= (rect.x() + rect.width())
and mousePos.y() >= (rect.y() + rect.height() - 7) and mousePos.y() <= (rect.y() + rect.height()))):
# logging.info("right bottom")
# 设置鼠标在右下角区域样式
self.setCursor(Qt.CrossCursor);
# 在右下角区域
self.cellBottomRight = True;
super().mouseMoveEvent(event);
# 鼠标点击事件
def mousePressEvent(self, event):
if (event.button() == Qt.LeftButton):
self.leftbuttonDown = True;
self.setCursor(Qt.SizeAllCursor);
else:
self.leftbuttonDown = False;
self.setCursor(Qt.ArrowCursor);
super().mousePressEvent(event); # 提交鼠标给控件
def mouseReleaseEvent(self, ev):
if self.leftbuttonDown and self.cellBottomRight:
itemList = self.selectedItems();
if len(itemList) > 0:
logging.info("dragbottom")
self.dragbottom.emit(itemList)
self.leftbuttonDown = False;
self.cellBottomRight = False;
self.setCursor(Qt.ArrowCursor);
super().mouseReleaseEvent(ev)
class Table(QWidget):
def __init__(self):
super().__init__()
self.setGeometry(300, 300, 500, 400)
self.setWindowTitle('QTableWidget的基本用法')
layout = QHBoxLayout()
self.table = MyTableWidget(None)
self.table.dragbottom.connect(self.dragbottom_trig)
m = 4
n = 3
self.table.setRowCount(4)
self.table.setColumnCount(3)
layout.addWidget(self.table)
self.table.setHorizontalHeaderLabels(['姓名', '性别', '体重(kg)'])
for i in range(m):
for j in range(n):
item1 = QTableWidgetItem('')
self.table.setItem(i, j, item1)
item1 = QTableWidgetItem('张三')
self.table.setItem(0, 0, item1)
item2 = QTableWidgetItem('男')
self.table.setItem(0, 1, item2)
item3 = QTableWidgetItem('50')
self.table.setItem(0, 2, item3)
self.setLayout(layout)
def dragbottom_trig(self, items):
print(items)
first = items[0]
col = first.column()
row = first.row()
print(dir(first))
v = first.text()
for one in items[1:]:
self.table.setItem(one.row(), one.column(), QTableWidgetItem(v))
if __name__ == "__main__":
app = QApplication(sys.argv)
form = Table()
form.show()
sys.exit(app.exec_())
'''
未完成项目的代码:付款管理系统PPM
最新推荐文章于 2024-08-13 18:29:56 发布