PyQt5 / PyQt

PyQt Examples(PyQt各种测试和例子) PyQt4 PyQt5
GNU Lesser General Public License v2.1
6.68k stars 1.97k forks source link

[问题] 重读Excel表格时出错 #89

Closed lm6810318 closed 5 years ago

lm6810318 commented 5 years ago

Environment : / 环境

我的问题:第一次路径错了,再输入第二个路径,程序就崩溃,不知问题在哪儿?

我的代码如下: import pandas as pd import openpyxl from PyQt5.QtWidgets import QApplication, QWidget,QPushButton,QFileDialog,QLineEdit,QComboBox,QLabel,QRadioButton,QGroupBox,QVBoxLayout,QMessageBox import sys from PyQt5.QtCore import Qt import re

class win(QWidget): def init(self): super().init() self.resize(800,500) self.setWindowTitle('成绩分析') self.btn=QPushButton('开始分析',self) self.btn.move(710,10) self.btn.clicked.connect(self.kaisifengxi) self.setWindowFlags(Qt.MSWindowsFixedSizeDialogHint) #窗口无法调整大小 self.btn1 = QPushButton('选择文件', self) self.btn1.move(10, 10) self.btn1.clicked.connect(self.wenjianxuze) self.qe=QLineEdit(self) #显示文件路径 self.qe.move(90,10) self.qe.resize(350,20) self.qe.setReadOnly(True) #只读 self.qe.textChanged.connect(self.wenbengaibian) # 文本发生改变时发出的信号

    self.cb=QComboBox(self)  #表格列表框
    self.cb.move(570,10)
    self.cb.resize(110,20)
    self.cb.currentIndexChanged[str].connect(self.biaogegaibian)  # 当前选中的索引发生改变时
    self.cb1 = QComboBox(self)  #学科列表框
    self.cb1.move(570, 50)
    self.cb1.resize(110, 20)

    self.lbl = QLabel('选择表格:',self)
    self.lbl.move(500,13)
    self.lbl1 = QLabel('选择学科:', self)
    self.lbl1.move(500,53)

    self.lb2=QLabel('总人数:',self)
    self.lb2.move(10,80)
    self.lb21 = QLabel('        ',self)
    self.lb21.move(80, 80)

    self.lb3 = QLabel('缺考人数:', self)
    self.lb3.move(10, 120)
    self.lb31 = QLabel('       ', self)
    self.lb31.move(80, 120)

    self.lb4 = QLabel('实考人数:', self)
    self.lb4.move(10, 160)
    self.lb41 = QLabel('       ', self)
    self.lb41.move(80, 160)

    self.lb5 = QLabel('总分:', self)
    self.lb5.move(10, 200)
    self.lb51 = QLabel('       ', self)
    self.lb51.move(80, 200)

    self.lb6 = QLabel('平均分:', self)
    self.lb6.move(10, 240)
    self.lb61 = QLabel('       ', self)
    self.lb61.move(80, 240)

    self.lb7 = QLabel('优秀人数:', self)
    self.lb7.move(10, 280)
    self.lb71 = QLabel('       ', self)
    self.lb71.move(80, 280)

    self.lb8 = QLabel('优秀率:', self)
    self.lb8.move(10, 320)
    self.lb81 = QLabel('       ', self)
    self.lb81.move(80, 320)

    self.gb=QGroupBox('满分值',self)
    self.gb.move(710,47)
    self.rb120 = QRadioButton('120')
    self.rb100=QRadioButton('100')
    self.vlayout=QVBoxLayout()
    self.gb.setLayout(self.vlayout)  # 组合框中添加布局
    self.vlayout.addWidget(self.rb100)
    self.rb100.toggled.connect(self.func)  # 按钮状态发生变化时发出信号
    self.rb120.toggled.connect(self.func1)
    self.vlayout.addWidget(self.rb120)
    self.rb100.setChecked(True)  # 设置为选中状态
    self.zrs=0  #总人数
    self.xks=0  #学科数
    self.mfz=100  #满分值
    self.qkrs=0  #缺考人数
    self.skrs=0  #实考人数
    self.zf=0   #总分
    self.pjf=0  #平均分
    self.yxrs=0  #优秀人数
    self.yxl=0  #优秀率

def biaogegaibian(self):#表格下拉列表框发生改变

    self.df = pd.read_excel(self.qe.text(), header=0, sheet_name=self.cb.currentText())  # 读取表格
    # header=0  所以文件的第一行必须是标题栏
    #返回值self.df的类型是:pandas.core.frame.DataFrame
    s = self.df.shape  # 返回总行数和总列数
    self.zrs = s[0]
    self.xks = s[1]
    self.lb21.setText(str(self.zrs))  #显示总人数
    s = self.df.columns  # 返回所有列标题
    self.cb1.clear()
    self.cb1.addItems(s)  # 把学科给下拉对话框

def kaisifengxi(self):#开始分析
    #*****对选中的学科进行数值验证*******
    self.df = pd.read_excel(self.qe.text(), header=0, sheet_name=self.cb.currentText())  # 读取表格
    p = re.compile('\d+\.?\d*')  # 创建正则对象--数值
    for i in range(self.zrs):
        s=str(self.df[self.cb1.currentText()].at[i])
        if s!='nan':
            s1 = re.search(p, s)  # 扫描整个字符串并返回第一个成功的匹配
            if s1==None:
                QMessageBox.warning(self, '请检查数据', '存在非数值字符')
                return
            else:
                s2=s1.group()  #提取匹配到的字符串
                if s!=s2:
                    QMessageBox.warning(self, '请检查数据', '存在非数值字符')
                    return
    #******数值验证结束*****下面找出缺考人数**********
    self.qkrs = 0
    for i in range(self.zrs):
        s = str(self.df[self.cb1.currentText()].at[i])
        if s=='nan':
            self.qkrs=self.qkrs+1
            self.lb31.setText(str(self.qkrs))
            self.skrs=self.zrs-self.qkrs
            self.lb41.setText(str(self.skrs))
    #****总分***
    self.zf = self.df[self.cb1.currentText()].sum()  # 对指定列求和--总分
    self.lb51.setText(str(self.zf))
    #***平均分*****
    self.pjf=self.zf/self.skrs
    self.lb61.setText(str(self.pjf))

    if self.mfz==100:#如果满分值=100
        self.yxrs=self.tongji(85,100)  #优秀人数
        self.lb71.setText(str(self.yxrs))
        self.yxl=self.yxrs/self.skrs  #优秀率
        self.lb81.setText(str(self.yxl))
    if self.mfz==120:  #如果满分值=120
        self.yxrs = self.tongji(102, 120)  #优秀人数
        self.lb71.setText(str(self.yxrs))
        self.yxl = self.yxrs / self.skrs  # 优秀率
        self.lb81.setText(str(self.yxl))

def func(self):#满分值100按钮状态变化时函数
    if self.rb100.isChecked():  # 返回按钮是否被选中,True选中
        self.mfz = 100

def func1(self):#满分值120按钮状态变化时函数
    if self.rb120.isChecked():  # 返回按钮是否被选中,True选中
        self.mfz = 120

def wenbengaibian(self):#路径编辑框文本发生变化时
    wb = openpyxl.load_workbook(self.r[0])  # 打开工作簿
    sheets = wb.sheetnames  # 获取wb中所有的表格

    wb.close()

    self.cb.clear()
    self.cb.addItems(sheets)  # 把表格给下拉对话框

def wenjianxuze(self):#选择文件
    self.r = QFileDialog.getOpenFileName(self, '请选择要打开的Excel文件', './', 'All(*.*);;Excel(*.xlsx)',
                                    'Excel(*.xlsx)')  # 显示文件选择对话框--获取打开的文件名称--获取一个文件
    #self.r[0]  是文件路径;self.r[1]  文件类型
    self.qe.setText(self.r[0]) #把文件路径给编辑框

def tongji(self,min,max):#统计分数函数
    #min max 分数段
    rs=0
    for i in range(self.zrs):
        ss=str(self.df[self.cb1.currentText()].at[i])
        if ss != 'nan' :
            ss=float(ss)
            if min<= ss <= max:
                rs=rs+1
    return rs  #返回分数段内的人数

if name=='main': app=QApplication(sys.argv) w=win() w.show() sys.exit(app.exec_())

892768447 commented 5 years ago

请在cmd中,运行代码,说不定能看到错误行数和异常内容。或者在代码中加上: import cgitb import sys sys.excepthook = cgitb.Hook(1, None, 5, sys.stderr, 'text')