第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > 编译原理-LL(1)语法分析器

编译原理-LL(1)语法分析器

时间:2020-07-15 23:55:09

相关推荐

编译原理-LL(1)语法分析器

目录

1,题目要求

2,实验结果

3,实验环境

4,假设

5,设计流程

6,注

7,代码

1,题目要求

输入:文法,字符串

输出:FIRST集,FOLLOW集,分析表,分析过程,消除左递归(包括直接和间接)后的文法

2,实验结果

3,实验环境

Python+PyQt+Pycharm

Python:编程语言;

PyQt:图形化界面设计工具;

Pycharm:Python编译器(需配置PyQt,QtDesigner)

4,假设

合理的假设对于降低设计难度、专注中心问题有着至关重要的作用。

假设非终结符全部用大写字母表示,终结符用小写字母表示;假设非终结符与终结符的个数均不超过26个(除“#”与“ε”);假设非终结符与终结符均为一个字符;假设具有相同左部符号的产生式,均合并为一个产生式,并用 “|” 隔开;假设文法输入框输入最后一个产生式后不按Enter键;

5,设计流程

使用QtDesigner设计图形界面,生成.ui文件,利用配置工具将.ui文件转换为.py文件,在.py文件里添加事件触发函数与主要程序函数。(推荐图书《PyQt 5快速开发与实战》)

6,注

仅供参考!想提高水平的同学,尽可能自己想办法解决遇到的问题;因笔者水平有限,代码较多,为方便理解已尽可能的做了注释;这只是个人对问题的理解与解决,并不代表标准答案;有不理解的地方可以在评论区留言;

7,代码

# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'D:\testPyQt5\PyQt5_code\test2.ui'## Created by: PyQt5 UI code generator 5.9.2## WARNING! All changes made in this file will be lost!from PyQt5 import QtCore, QtGui, QtWidgetsimport sysfrom PyQt5.QtGui import QStandardItemModel, QStandardItemfrom PyQt5.QtWidgets import QHeaderViewclass Ui_Form(object):generative = [] # 存放textEdit中的文法generative_ = {} # 字典存放处理过的产生式(一个key对应一个list)input = '' # 存放输入串ter_colt = []non = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V','W', 'X', 'Y', 'Z']non_colt = []ter_colt_copy = [] # 去掉空字的终结符集合first_set = {} # 字典存放处理first集(一个key对应一个list)follow_set = {} # 字典存放处理follow集(一个key对应一个list)analyze_table = [] # 预测分析表state = 0 # 状态,0:Null;1:Accepted;2:Error;3:产生式含有左递归message = '' # 记录状态框的输出信息judge = {} # 用以判断间接左递归 存放"key=非终结符,value=对应产生式的首个非终结符" 以字典模拟树judge_list = []recursion_tag = -1 # 是否含左递归的标记,-1:尚未确定,0:不含 1:含直接左递归,2:含间接左递归directRecList = [] # 记录含直接左递归的非终结符def setupUi(self, Form):Form.setObjectName("Form")Form.resize(954, 610)self.line = QtWidgets.QFrame(Form)self.line.setGeometry(QtCore.QRect(320, 10, 20, 571))self.line.setFrameShape(QtWidgets.QFrame.VLine)self.line.setFrameShadow(QtWidgets.QFrame.Sunken)self.line.setObjectName("line")self.tabWidget = QtWidgets.QTabWidget(Form)self.tabWidget.setEnabled(True)self.tabWidget.setGeometry(QtCore.QRect(350, 20, 571, 501))self.tabWidget.setObjectName("tabWidget")self.PROCESS = QtWidgets.QWidget()self.PROCESS.setObjectName("PROCESS")self.tableView_3 = QtWidgets.QTableView(self.PROCESS)self.tableView_3.setGeometry(QtCore.QRect(0, 0, 561, 481))self.tableView_3.setObjectName("tableView_3")self.tabWidget.addTab(self.PROCESS, "")self.FIRST = QtWidgets.QWidget()self.FIRST.setObjectName("FIRST")self.tableView = QtWidgets.QTableView(self.FIRST)self.tableView.setGeometry(QtCore.QRect(0, 0, 561, 481))self.tableView.setObjectName("tableView")self.tabWidget.addTab(self.FIRST, "")# self.model = QStandardItemModel(20,10)self.FOLLOW = QtWidgets.QWidget()self.FOLLOW.setObjectName("FOLLOW")self.tableView_2 = QtWidgets.QTableView(self.FOLLOW)self.tableView_2.setGeometry(QtCore.QRect(0, 0, 561, 481))self.tableView_2.setObjectName("tableView_2")self.tabWidget.addTab(self.FOLLOW, "")self.ANALYZE = QtWidgets.QWidget()self.ANALYZE.setObjectName("ANALYZE")self.tableView_4 = QtWidgets.QTableView(self.ANALYZE)self.tableView_4.setGeometry(QtCore.QRect(0, 0, 561, 481))self.tableView_4.setObjectName("tableView_4")self.tabWidget.addTab(self.ANALYZE, "")self.pushButton = QtWidgets.QPushButton(Form)self.pushButton.setGeometry(QtCore.QRect(120, 550, 75, 23))self.pushButton.setObjectName("pushButton")self.pushButton.clicked.connect(self.btnRun_Clicked) # 将按钮与函数 btnRun_Clicked绑定self.label_3 = QtWidgets.QLabel(Form)self.label_3.setGeometry(QtCore.QRect(350, 550, 54, 12))self.label_3.setObjectName("label_3")self.textBrowser = QtWidgets.QTextBrowser(Form)self.textBrowser.setGeometry(QtCore.QRect(400, 540, 481, 31))self.textBrowser.setObjectName("textBrowser")self.widget = QtWidgets.QWidget(Form)self.widget.setGeometry(QtCore.QRect(40, 40, 258, 481))self.widget.setObjectName("widget")self.verticalLayout = QtWidgets.QVBoxLayout(self.widget)self.verticalLayout.setContentsMargins(0, 0, 0, 0)self.verticalLayout.setObjectName("verticalLayout")self.label = QtWidgets.QLabel(self.widget)self.label.setObjectName("label")self.verticalLayout.addWidget(self.label)self.textEdit = QtWidgets.QTextEdit(self.widget)self.textEdit.setObjectName("textEdit")self.verticalLayout.addWidget(self.textEdit)spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)self.verticalLayout.addItem(spacerItem)self.label_2 = QtWidgets.QLabel(self.widget)self.label_2.setObjectName("label_2")self.verticalLayout.addWidget(self.label_2)self.lineEdit = QtWidgets.QLineEdit(self.widget)self.lineEdit.setObjectName("lineEdit")self.verticalLayout.addWidget(self.lineEdit)self.retranslateUi(Form)self.tabWidget.setCurrentIndex(0)QtCore.QMetaObject.connectSlotsByName(Form)def retranslateUi(self, Form):_translate = QtCore.QCoreApplication.translateForm.setWindowTitle(_translate("Form", "Form"))self.tabWidget.setTabText(self.tabWidget.indexOf(self.PROCESS), _translate("Form", "分析过程"))self.tabWidget.setTabText(self.tabWidget.indexOf(self.FIRST), _translate("Form", "FIRST集"))self.tabWidget.setTabText(self.tabWidget.indexOf(self.FOLLOW), _translate("Form", "FOLLOW集"))self.tabWidget.setTabText(self.tabWidget.indexOf(self.ANALYZE), _translate("Form", "分析表"))self.pushButton.setText(_translate("Form", "Run"))self.label_3.setText(_translate("Form", "State:"))self.label.setText(_translate("Form", "文法(相同非终结符产生式用|隔开,不要回车):"))self.label_2.setText(_translate("Form", "输入:"))def isTerminal(self, c): # 若c介于A-Z之间则认为是非终结符(注意添加 self参数)if c < 'A' or c > 'Z':return Trueelse:return Falsedef getFirstSet(self, target): # 此函数递归调用for VN in self.generative_.keys(): # 遍历每个非终结符,直到找到targetif VN == target:for formula in self.generative_[VN]: # 遍历非终结符的所有产生式time = 0 # 记录产生式右侧的非终结符的first集中含ε的个数,若等于右侧产生式的长度,则将ε加入产生式左侧非终结符的first集中for c in formula: # 分析产生式if self.isTerminal(c): # 若为终结符则直接加入first集self.first_set.setdefault(VN, []).append(c) # 由于set不支持索引 故使用list而不是set()breakelse:self.getFirstSet(c)if 'ε' in self.first_set[c]: # self.first_set[c]其实是指一个listtime += 1else:for value in self.first_set[c]:self.first_set.setdefault(VN, []).append(value)if time == len(formula):self.first_set.setdefault(VN, []).append('ε')def getFollowSet(self, target):for VN in self.generative_.keys():for formula in self.generative_[VN]:length = len(formula)for i in range(len(formula)):flag = 1 # 作为判断E->ABC...中 A后面的终结符的first集中是否含ε的标志 1:含有if formula[i] == target and flag == 1 and i < length - 1:pos = icha = formula[pos + 1]if self.isTerminal(cha): # 例如E->Ab,求A的follow集 发现A后为终结符 则直接跳过此产生式self.follow_set.setdefault(target, []).append(cha)breakelse: # 此循环用于解决E->ABCDe,类似的target后多个终结符的first集含有$的情况while flag == 1 and pos < len(formula) - 1:if self.isTerminal(cha):self.follow_set.setdefault(VN, []).append(cha)flag = 0breakelse:tag = 0 # 标记当前非终结符的first集中是否含ε, 0:否for j in range(len(self.first_set[cha])):cha1 = self.first_set[cha][j]if cha1 != 'ε':self.follow_set.setdefault(target, []).append(cha1)else:tag = 1if tag == 0: # 若当前非终结符的first集中不否含ε, 则可分析下一个产生式flag = 0pos += 1if pos == len(formula) - 1 and target != VN:self.getFollowSet(VN)for cha2 in self.follow_set[VN]:self.follow_set.setdefault(target, []).append(cha2)elif target != VN and formula[i] == target and flag == 1 and i == length - 1:self.getFollowSet(VN)for cha2 in self.follow_set[VN]:self.follow_set.setdefault(target, []).append(cha2)def getAnalyzeTable(self):for VN in self.non_colt:pos_x = self.non_colt.index(VN)for formula in self.generative_[VN]:for c in formula:if self.isTerminal(c) and c != 'ε': # 分析表中的终结符无εpos_y = self.ter_colt_copy.index(c)self.analyze_table[pos_x][pos_y] = formulabreakelif c != 'ε': # c为非终结符时flag = 0 # 若flag为0表明非终结符的first集中不含εfor c1 in self.first_set[c]:if c1 == 'ε':for c2 in self.follow_set[VN]:pos_y = self.ter_colt_copy.index(c2)self.analyze_table[pos_x][pos_y] = 'ε'flag = 1else:pos_y = self.ter_colt_copy.index(c1)self.analyze_table[pos_x][pos_y] = formulaif flag == 0:break # 分析下一个产生式else: # c为空字时for c2 in self.follow_set[VN]:pos_y = self.ter_colt_copy.index(c2)self.analyze_table[pos_x][pos_y] = 'ε'def analyzeProcess(self):analyse_stack = []analyse_stack.append('#')analyse_stack.append(self.non_colt[0]) # 分析栈# print(analyse_stack)remain_part = list(self.input) # 剩余输入串formula = '' # 所用产生式action = ['初始化'] # 动作(采用列表形式)time = 0 # 记录步骤数self.model_3 = QStandardItemModel(30, 4)label_x = ['分析栈', '剩余输入串', '所用产生式', '动作']self.model_3.setHorizontalHeaderLabels(label_x)temp = ''.join(analyse_stack)item = QStandardItem(temp)self.model_3.setItem(0, 0, item)temp = ''.join(remain_part)item = QStandardItem(temp)self.model_3.setItem(0, 1, item)item = QStandardItem(formula)self.model_3.setItem(0, 2, item)temp = ','.join(action)item = QStandardItem(temp)self.model_3.setItem(0, 3, item)# print(analyse_stack)while not (len(analyse_stack) == 1 and len(remain_part) == 1):left = analyse_stack[-1]right = remain_part[0]if not self.isTerminal(left):formula = self.analyze_table[self.non_colt.index(left)][self.ter_colt_copy.index(right)]if left == right:time += 1del analyse_stack[-1]del remain_part[0]formula = ''action = ['GETNEXT']temp = ''.join(analyse_stack)item = QStandardItem(temp)self.model_3.setItem(time, 0, item)temp = ''.join(remain_part)item = QStandardItem(temp)self.model_3.setItem(time, 1, item)item = QStandardItem(formula)self.model_3.setItem(time, 2, item)temp = ','.join(action)item = QStandardItem(temp)self.model_3.setItem(time, 3, item)else:if formula == 0:self.state = 2 # 输入串无法解析self.message = 'Error: There is no way between \'' + left + '\' and \'' + right + '\''breakelse:if formula == 'ε':time += 1 # 次数加一del analyse_stack[-1] # POPformula = left + '->' + 'ε'action = ['POP']temp = ''.join(analyse_stack)item = QStandardItem(temp)self.model_3.setItem(time, 0, item)temp = ''.join(remain_part)item = QStandardItem(temp)self.model_3.setItem(time, 1, item)item = QStandardItem(formula)self.model_3.setItem(time, 2, item)temp = ','.join(action)item = QStandardItem(temp)self.model_3.setItem(time, 3, item)else:time += 1del analyse_stack[-1] # POPli = list(formula)li.reverse()analyse_stack += liformula = left + '->' + formulaact = 'PUSH(' + ''.join(li) + ')'action = ['POP', act]temp = ''.join(analyse_stack)item = QStandardItem(temp)self.model_3.setItem(time, 0, item)temp = ''.join(remain_part)item = QStandardItem(temp)self.model_3.setItem(time, 1, item)item = QStandardItem(formula)self.model_3.setItem(time, 2, item)temp = ','.join(action)item = QStandardItem(temp)self.model_3.setItem(time, 3, item)if len(analyse_stack) == 1 and len(remain_part) == 1:self.state = 1self.tableView_3.horizontalHeader().setStretchLastSection(True)self.tableView_3.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)self.tableView_3.setModel(self.model_3)def isLeftRecursion(self, target): # 递归判断间接左递归self.judge_list.append(target)if target in self.judge and self.recursion_tag == -1: # 是否递归还未确定for V in self.judge[target]:if self.judge_list.count(V) > 0: # 若列表中已含有当前非终结符self.judge_list.append(V)self.state = 3self.recursion_tag = 2returnself.isLeftRecursion(V)if self.recursion_tag == 0:self.judge_list.remove(target)elif target not in self.judge: # 目标元素不在间接左递归的judge中 eg.S->ab|c 递归中断 即循环链条中断self.recursion_tag = 0returndef getNewNon(self): # 返回新的非终结符for cha in self.non:if cha not in self.non_colt:return chadef delRecursion(self):if 'ε' not in self.ter_colt:self.ter_colt.append('ε')if self.recursion_tag == 1:for cha in self.directRecList: # 消除直接左递归newNon = self.getNewNon() # 获得新标识符self.non_colt.append(newNon) # 加入非终结符集合for formula in self.generative_[cha]: # 遍历此非终结符的所有产生式if cha == formula[0]:s1 = formula[1:] # E->E+T 提取右侧产生式中的+Tformula_ = s1 + newNon # 替换原先的产生式self.generative_.setdefault(newNon, []).append(formula_) # 为新终结符创建产生式self.generative_.setdefault(newNon, []).append('ε') # 为新终结符创建产生式self.generative_[cha].remove(formula) # 删除含直接左递归因素的产生式i = 0 # 由于下面循环中对循环条件generative_做出修改 迭代顺序会与想象中不同 故用i作为下标进行处理for formula1 in self.generative_[cha]: # 修改其余产生式formula4 = formula1 + newNonself.generative_[cha].remove(formula1)self.generative_.setdefault(cha).insert(i, formula4)i += 1if self.recursion_tag == 2: # 间接左递归 以产生式 S->Qc|c;Q->Rb|b;R->Sa|a为例#print(self.generative_)judge_list_copy = self.judge_list.copy()del judge_list_copy[-1] # 去掉[S,Q,R,S]中的Swhile len(judge_list_copy) > 1:# print(self.non_colt)for VN in self.non_colt: # 遍历所有产生式 注意是所有for formula2 in self.generative_[VN]:flag = 0 # 判断产生式中是否含此符号for cha1 in formula2:if cha1 == judge_list_copy[-1]: # 等于judge_list_copy的末尾元素 自下向上进行替换flag = 1breakif flag == 1: # 其中一个产生式含待替换的VN 需替换的次数为VN的产生式个数s2 = formula2 # 副本if formula2 in self.generative_[VN]:self.generative_[VN].remove(formula2) # 删除该产生式for formula3 in self.generative_[judge_list_copy[-1]]: # 用R的各产生式替换s3 = s2s3 = s3.replace(judge_list_copy[-1], formula3)self.generative_.setdefault(VN, []).append(s3) # 插入产生式集中self.non_colt.remove(judge_list_copy[-1])del self.generative_[judge_list_copy[-1]]del judge_list_copy[-1]print(self.generative_)# 至此 会出现 S->Sabc|abc|bc|c 再消除一次直接左递归即可newNon = self.getNewNon() # 获得新标识符self.non_colt.append(newNon) # 加入非终结符集合cha = self.judge_list[0]for formula in self.generative_[cha]: # 遍历此非终结符的所有产生式if cha == formula[0]: # 找到含左递归因子的产生式s1 = formula[1:] # E->E+T 提取右侧产生式中的+Tformula_ = s1 + newNon # 替换原先的产生式self.generative_.setdefault(newNon, []).append(formula_) # 为新终结符创建产生式self.generative_.setdefault(newNon, []).append('ε') # 为新终结符创建产生式self.generative_[cha].remove(formula) # 删除含直接左递归因素的产生式print(self.generative_[cha])print(123)'''此方法不行!!!移除元素,并在末尾添加元素会使迭代过程超出预期for other in self.generative_[cha]: # 修改其余产生式s4 = other + newNonself.generative_[cha].remove(other)self.generative_.setdefault(cha, []).append(s4)print(self.generative_[cha])break'''i = 0for other in self.generative_[cha]: # 修改其余产生式s4 = other + newNonself.generative_[cha].remove(other)self.generative_.setdefault(cha).insert(i, s4)i += 1print(self.generative_[cha])break# 将形如E->A|B|$的产生式处理为{'E':['A','B','$'],...}的字典形式def inputAndSolve(self):self.generative = self.textEdit.toPlainText().split('\n')self.input = '' + self.lineEdit.text()terminal = '' # 临时存放非终结符# 规范化产生式for temp in self.generative:s = '' # 临时存放产生式i = 0while i < len(temp):if i == 0:terminal = temp[0]if temp[0] not in self.non_colt:self.non_colt.append(temp[0])i += 3 # 跳过E->A中的->elif i >= 3:if temp[i] == '|':i += 1self.generative_.setdefault(terminal, []).append(s)s = ''continueelse:if self.isTerminal(temp[i]):if temp[i] not in self.ter_colt:self.ter_colt.append(temp[i])s += temp[i]i += 1self.generative_.setdefault(terminal, []).append(s) # 每个非终结符的最后一个产生式需要self.ter_colt_copy = self.ter_coltif 'ε' in self.ter_colt_copy:self.ter_colt_copy.remove('ε')self.ter_colt_copy.append('#')'''RECURSION'''# 这里做简化处理 认为文法中只存在间接左递归或直接左递归中的一种 且间接左递归只含有一条循环链# 若想完善此点 可用while循环不断判断、消除 直到确认无递归出现为止for VN in self.generative_.keys(): # 寻找并判断直接左递归for formula in self.generative_[VN]:cha1 = formula[0]if not self.isTerminal(cha1):self.judge.setdefault(VN, []).append(cha1) # 记录每个非终结符的各个产生式的首个非终结符 为消除间接左递归准备if VN == cha1:self.directRecList.append(cha1) # 记录含直接左递归的非终结符self.recursion_tag = 1 # 确定为直接左递归self.state = 3self.message += 'DirectLeftRecurtion:'s = VN + '->' + formula + '\n'self.message += s# print(self.judge)为消除间接左递归准备if self.recursion_tag != 1: # 若非直接左递归则继续self.isLeftRecursion(self.non_colt[0])if self.recursion_tag == 2: # 若此时确定recursion_tag为2 则为间接左递归self.message = 'IndirectLeftRecurtion:'self.message += '->'.join(self.judge_list)# print(self.message)# print(self.recursion_tag)if self.recursion_tag == 1 or self.recursion_tag == 2: # 含有左递归self.delRecursion()textEditBoxList = [] # 显示修改后的文法textEditBoxList.extend(self.generative)textEditBoxList.append(' ')bound = '***左递归消除后的文法为***'textEditBoxList.append(bound)textEditBoxList.append(' ')for VN in self.generative_:str = VN + '->'for formula in self.generative_[VN]:if formula == self.generative_[VN][-1]:str = str + formulaelse:str = str + formula + '|'textEditBoxList.append(str)textEditBoxStr = '\n'.join(textEditBoxList)self.textEdit.setText(textEditBoxStr)self.state = 0 # 若含有左递归 则已消除print(self.generative_)# 接下来进行过程的求解if self.state == 0:'''FIRST'''# 求first集for VN in self.generative_.keys():self.getFirstSet(VN)# 去除first集key对应的list中重复的非终结符for VN in self.first_set:test = list(set(self.first_set[VN]))self.first_set[VN] = test# 将first集作为数据源以QTableView的形式展示出来self.model = QStandardItemModel(len(self.non_colt), len(self.ter_colt))label_y = []for s in self.non_colt:label_y.append(s)self.model.setVerticalHeaderLabels(label_y)for row in range(len(self.non_colt)):for column in range(len(self.first_set[self.non_colt[row]])):item = QStandardItem(self.first_set[self.non_colt[row]][column])self.model.setItem(row, column, item)self.tableView.horizontalHeader().setStretchLastSection(True)self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)self.tableView.setModel(self.model)# print(self.first_set)'''FOLLOW'''# 求follow集for VN in self.non_colt:if VN == self.generative[0][0]: # 在开始符E的follow集中加入#self.follow_set.setdefault(VN, []).append('#')self.getFollowSet(VN)# 去除follow集key对应的list中重复的非终结符for VN in self.follow_set:test = list(set(self.follow_set[VN]))self.follow_set[VN] = test# 将follow集作为数据源以QTableView的形式展示出来self.model_2 = QStandardItemModel(len(self.non_colt), len(self.ter_colt))self.model_2.setVerticalHeaderLabels(label_y)for row in range(len(self.non_colt)):for column in range(len(self.follow_set[self.non_colt[row]])):item = QStandardItem(self.follow_set[self.non_colt[row]][column])self.model_2.setItem(row, column, item)self.tableView_2.horizontalHeader().setStretchLastSection(True)self.tableView_2.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)self.tableView_2.setModel(self.model_2)'''ANALYZE'''self.analyze_table = [[0 for col in range(len(self.ter_colt))] for row in range(len(self.non_colt))]self.getAnalyzeTable()self.model_4 = QStandardItemModel(len(self.non_colt), len(self.ter_colt_copy))label_x = []label_y = []for s in self.ter_colt_copy:label_x.append(s)for s in self.non_colt:label_y.append(s)self.model_4.setHorizontalHeaderLabels(label_x)self.model_4.setVerticalHeaderLabels(label_y)for row in range(len(self.non_colt)):for column in range(len(self.ter_colt_copy)):item = QStandardItem(self.analyze_table[row][column])self.model_4.setItem(row, column, item)self.tableView_4.horizontalHeader().setStretchLastSection(True)self.tableView_4.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)self.tableView_4.setModel(self.model_4)print(self.analyze_table)'''PROCESS'''self.analyzeProcess()if self.state == 0 and self.recursion_tag == 0:self.message = 'Null'elif self.state == 1 and self.recursion_tag == 0:self.message = 'Accepted!\n'# state等于2,3的情况已经在分析过程中添加到message中self.textBrowser.setText(self.message)def btnRun_Clicked(self):self.inputAndSolve()if __name__ == "__main__":import sysapp = QtWidgets.QApplication(sys.argv)Form = QtWidgets.QWidget()ui = Ui_Form()ui.setupUi(Form)Form.show()sys.exit(app.exec_())

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。