未完成项目的代码:付款管理系统PPM

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_())
'''

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值