PySide6打包Mac应用时窗口闪退无法输入问题求助
问题:PySide6打包Mac应用闪退,无法输入
我有一个功能正常的Python成绩计算程序,能接收作业名称、日期、分数及占比等输入并计算总分,输入逻辑适配我校网站格式。现在尝试用PySide6把它打包成Mac应用,但运行时窗口弹出后立刻闪退,根本没法输入。下面是原程序代码和我写的PySide6代码:
原程序代码
raw_grade = [] indexes = [] index = 0 score = [] percent = [] fi_score = [] raw = [] add = 0 denom = 0 total = 0 import sys import re from operator import itemgetter print("Enter the data") def multi_input(): try: while True: data=input() if not data: break yield data except KeyboardInterrupt: return data = list(multi_input()) for i in range(3, len(data),4): index = i indexes.append(i) raw_grade = [data[id] for id in indexes] for i in range(len(raw_grade)): gc = raw_grade[i].split('\t') raw.append(gc) for i in range(len(raw)): percent.append(raw[i][3]) score.append(raw[i][4]) for i in range(len(score)): use_score = score[i].split('/') fi_score.append(use_score) score = fi_score score = [value for value in score if value != ['']] for i in range(len(score)): score[i] = [float(i) for i in score[i]] for i in range(len(score)): try: score[i] = score[i][0]/score[i][1]*100 except ZeroDivisionError: result = 0 for i in range(len(percent)): try: percent[i] = percent[i].replace('%', '') except ZeroDivisionError: result = 0 percent = [value for value in percent if value != ''] for i in range(len(percent)): try: percent = [float(i) for i in percent] except ZeroDivisionError: result = 0 print("graded assignments: ", len(score)) #calculation part for i in range(len(score)): add = score[i]*percent[i]/100 total = total + add denom = denom + percent[i] total = total/denom*100 print(f"{total:05.2f}")
目前编写的PySide6代码
from PySide6 import QtCore, QtWidgets from PySide6.QtWidgets import QMainWindow, QWidget, QLabel, QLineEdit,QApplication from PySide6.QtWidgets import QPushButton from PySide6.QtCore import QSize raw_grade = [] indexes = [] index = 0 score = [] percent = [] fi_score = [] raw = [] add = 0 denom = 0 total = 0 import sys import re from operator import itemgetter def multi_input(self): try: while True: self.nameLabel = QLabel(self) self.nameLabel.setText('Name:') self.line = QLineEdit(self) if not self.line.text(): break yield self.line.text() except KeyboardInterrupt: return class MainWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) raw_grade = [] indexes = [] index = 0 score = [] percent = [] fi_score = [] raw = [] add = 0 denom = 0 total = 0 self.setMinimumSize(QSize(320, 140)) self.setWindowTitle("PyQt Line Edit example (textfield) - pythonprogramminglanguage.com") multi_input(self) self.line = list(multi_input(self)) pybutton = QPushButton('OK', self) pybutton.clicked.connect(self.clickMethod) pybutton.resize(200,32) pybutton.move(80, 60) for i in range(3, len(self.line), 4): index = i indexes.append(i) raw_grade = [self.line[id] for id in indexes] score = fi_score score = [value for value in score if value != ['']] for i in range(len(raw_grade)): gc = raw_grade[i].split('\t') raw.append(gc) for i in range(len(raw)): percent.append(raw[i][3]) score.append(raw[i][4]) for i in range(len(score)): use_score = score[i].split('/') fi_score.append(use_score) for i in range(len(score)): score[i] = [float(i) for i in score[i]] for i in range(len(score)): try: score[i] = score[i][0] / score[i][1] * 100 except ZeroDivisionError: result = 0 for i in range(len(percent)): try: percent[i] = percent[i].replace('%', '') except ZeroDivisionError: result = 0 percent = [value for value in percent if value != ''] for i in range(len(percent)): try: percent = [float(i) for i in percent] except ZeroDivisionError: result = 0 print("graded assignments: ", len(score)) # calculation part for i in range(len(score)): add = score[i] * percent[i] / 100 total = total + add denom = denom + percent[i] self.line = total / denom * 100 print('Your name: ' + self.line.text()) def clickMethod(self): print('Your name: ' + self.line.text()) if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() app.exec()
问题原因及修复方案
核心问题
- 初始化阶段直接执行计算逻辑:在
MainWindow的__init__里立刻执行所有计算代码,此时UI还没渲染完成,且没有等待用户输入,空数据直接引发错误导致闪退。 - UI逻辑错误:
multi_input函数在循环里重复创建QLabel和QLineEdit,完全不符合用户输入的交互逻辑,而且直接把self.line覆盖为列表,后续调用.text()会报错。 - 变量作用域混乱:全局变量和类内局部变量重复定义,导致数据传递出错。
修复后的代码
from PySide6 import QtWidgets, QtCore from PySide6.QtWidgets import (QMainWindow, QTextEdit, QPushButton, QVBoxLayout, QWidget, QLabel, QMessageBox) import sys class GradeCalculator(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("成绩计算器") self.setMinimumSize(600, 400) # 主部件和布局 central_widget = QWidget() self.setCentralWidget(central_widget) layout = QVBoxLayout(central_widget) # 输入区域 input_label = QLabel("粘贴从学校网站复制的成绩数据:") self.input_text = QTextEdit() self.input_text.setPlaceholderText("请粘贴多行成绩数据,格式与学校网站一致...") layout.addWidget(input_label) layout.addWidget(self.input_text) # 计算按钮 calc_btn = QPushButton("计算总分") calc_btn.clicked.connect(self.calculate_total) layout.addWidget(calc_btn) # 结果显示区域 self.result_label = QLabel("计算结果:") layout.addWidget(self.result_label) def calculate_total(self): # 获取输入数据 input_data = self.input_text.toPlainText().splitlines() if not input_data: QMessageBox.warning(self, "警告", "请输入成绩数据!") return raw_grade = [] indexes = [] score = [] percent = [] fi_score = [] raw = [] add = 0.0 denom = 0.0 total = 0.0 # 提取有效数据行(和原程序逻辑一致) for i in range(3, len(input_data), 4): indexes.append(i) raw_grade = [input_data[id] for id in indexes] # 解析成绩和占比 for item in raw_grade: gc = item.split('\t') if len(gc) >=5: # 确保数据格式正确 raw.append(gc) percent.append(gc[3]) score.append(gc[4]) # 处理分数 for s in score: use_score = s.split('/') if use_score != ['']: fi_score.append(use_score) # 转换为数值并计算百分比分数 valid_scores = [] for s in fi_score: try: if len(s) ==2: score_num = float(s[0])/float(s[1])*100 valid_scores.append(score_num) except (ZeroDivisionError, ValueError): continue # 处理占比 valid_percents = [] for p in percent: p_clean = p.replace('%', '') if p_clean != '': try: valid_percents.append(float(p_clean)) except ValueError: continue # 确保分数和占比数量匹配 if len(valid_scores) != len(valid_percents): QMessageBox.warning(self, "错误", "数据格式异常,分数和占比数量不匹配!") return if not valid_scores: QMessageBox.warning(self, "错误", "未找到有效成绩数据!") return # 计算总分 for s, p in zip(valid_scores, valid_percents): add += s * p / 100 denom += p if denom ==0: QMessageBox.warning(self, "错误", "有效占比总和为0,无法计算总分!") return total = add / denom *100 self.result_label.setText(f"计算结果:已评作业数量 {len(valid_scores)},总分 {total:05.2f}") if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) window = GradeCalculator() window.show() sys.exit(app.exec())
关键修改点
- 使用
QTextEdit替代单行输入框,适配原程序的多行粘贴输入需求。 - 将所有计算逻辑移到按钮点击的槽函数
calculate_total中,确保用户输入完成后再触发计算。 - 添加了数据校验和错误提示,避免空输入、格式错误导致的崩溃。
- 整理了变量作用域,全部使用类内局部变量,避免全局变量干扰。
- 优化了UI布局,使用垂直布局让界面更合理,操作更直观。
内容的提问来源于stack exchange,提问作者pyptpr
相关产品推荐
相关产品推荐

