python - pyqt5坚持进口
问题描述
我正在使用 pyqt5 制作一个 GUI,在 1 个文件中我放置了整个 GUI 应用程序,在另一个文件中我放置了用于在 Excel 电子表格中查找姓名和姓氏的代码。在 GUI 中,我希望用户输入名字和姓氏,然后按下从 file2 激活 start() 的搜索按钮。在文件 2 中,它搜索电子表格并从中获取数据,数据需要转到 file1 并进入 GUI 的标签,但它总是要求提供 self 参数,因为它是 pyqt5 所需的类。
文件1:
from PyQt5.QtWidgets import QApplication, QMainWindow, QLineEdit, QComboBox, QCheckBox, QSpinBox, QLabel, QMessageBox, QPushButton
import sys
from vind_gebruiker_zaterdag import start
class Window(QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.setWindowTitle("Inschrijven Mosselen")
self.setGeometry(300, 100, 700, 700)
self.initUI()
def initUI(self):
global mg, mgh, mk, mkh, pg, pgh, pk, pkh, dag, betaald, bedrag
mg = "0"
mgh = "0"
mk = "0"
mkh = "0"
pg = "0"
pgh = "0"
pk = "0"
pkh = "0"
brood = None
betaald = "Nee"
found = "Niet gevonden"
self.vind_voornaam = QLineEdit(self)
self.vind_voornaam.move(100, 100)
self.vind_voornaam.setFixedWidth(200)
self.vind_voornaam.setFixedHeight(60)
font = self.vind_voornaam.font()
font.setPointSize(11)
self.vind_voornaam.setFont(font)
self.vind_voornaam.setPlaceholderText("Voornaam")
print(self.vind_voornaam.text())
self.vind_achternaam = QLineEdit(self)
self.vind_achternaam.move(350, 100)
self.vind_achternaam.setFixedWidth(200)
self.vind_achternaam.setFixedHeight(60)
font = self.vind_achternaam.font()
font.setPointSize(11)
self.vind_achternaam.setFont(font)
self.vind_achternaam.setPlaceholderText("achternaam")
print(self.vind_achternaam.text())
self.Input = QLabel("Input", self)
self.Input.move(305, 45)
font = self.Input.font()
font.setPointSize(13)
self.Input.setFont(font)
self.Output = QLabel("Output", self)
self.Output.move(300, 200)
font = self.Output.font()
font.setPointSize(13)
self.Output.setFont(font)
self.search = QPushButton("Zoek", self)
self.search.move(275, 175)
self.search.setFixedWidth(100)
self.search.setFixedHeight(25)
font = self.search.font()
font.setPointSize(12)
self.search.setFont(font)
self.search.clicked.connect(self.clicked)
self.next = QPushButton("Volgende", self)
self.next.move(250, 625)
self.next.setFixedWidth(200)
self.next.setFixedHeight(60)
font = self.next.font()
font.setPointSize(12)
self.next.setFont(font)
self.gevonden = QLabel(f"{found}", self)
self.gevonden.move(285, 235)
font = self.gevonden.font()
font.setPointSize(11)
self.gevonden.setFont(font)
self.mg = QLabel(f"Mosselen groot: {mg}", self)
self.mg.move(50, 250)
font = self.mg.font()
font.setPointSize(11)
self.mg.setFont(font)
self.Subject = QLabel("Vind Inschrijving", self)
self.Subject.move(30, 30)
font = self.Subject.font()
font.setPointSize(15)
self.Subject.setFont(font)
self.update()
def assign(self, mg1, mgh1, mk1, mkh1, pg1, pgh1, pk1, pkh1, betaald1, dag1, bedrag1, found1):
mg = mg1
mgh = mgh1
mk = mk1
mkh = mkh1
pg = pg1
pgh = pgh1
pk = pk1
pkh = pkh1
betaald = betaald1
dag = dag1
bedrag = bedrag1
found = found1
self.mg.setText(mg)
def update(self):
self.Subject.adjustSize()
self.gevonden.adjustSize()
def clicked(self):
start(self.vind_voornaam.text(), self.vind_achternaam.text())
def window():
app = QApplication(sys.argv)
win = Window()
win.show()
sys.exit(app.exec_())
if __name__ == "__main__":
window()
该文件采用姓名和姓氏并在电子表格中搜索并返回该行中的其他数据。
文件2:
import openpyxl as xl
wb = xl.load_workbook('mosselen 2020.xlsx', data_only=True)
ws1 = wb['ZATERDAG']
ws2 = wb['ZONDAG']
def start(voornaam1, achternaam1):
global found
voornaam = voornaam1
achternaam = achternaam1
active_sheet = ""
row_index = None
min_row = 5
max_row = ws1.max_row - 10
if voornaam == "":
voornaam = None
if achternaam == "":
achternaam = None
for cell in ws1.iter_rows(min_row=min_row, min_col=4, max_col=5, max_row=max_row):
if set((c.value for c in cell)) == {voornaam, achternaam}:
row_index = cell[0].row
print('Gevonden')
found = "Gevonden"
active_sheet = "ZATERDAG"
for cell2 in ws1.iter_rows(min_row=cell[0].row, min_col=6, max_col=33, max_row=cell[0].row):
if voornaam is None:
voornaam = ''
break
if cell2[9].value == 'j':
cell2[27].value = 'al betaald'
else:
cell2[27].value = cell2[27].value
for cell3 in cell2:
if cell3.value is None:
cell3.value = "0"
print(f'besteling:\nMG {cell2[0].value}\nMGH {cell2[1].value}\nMK {cell2[2].value}\nMKH {cell2[3].value}\n'
f'PG {cell2[4].value}\nPGH {cell2[5].value}\nPK {cell2[6].value}\nPKH {cell2[7].value}\nBetaald: {cell2[9].value}\n\nTe betalen: {cell2[27].value}\n ')
mg = cell2[0].value
mgh = cell2[1].value
mk = cell2[2].value
mkh = cell2[3].value
pg = cell2[4].value
pgh = cell2[5].value
pk = cell2[6].value
pkh = cell2[7].value
betaald = cell2[9].value
bedrag = cell2[27].value
dag = active_sheet
print(dag)
assign_var(mg, mgh, mk, mkh, pg, pgh, pk, pkh, betaald, dag, bedrag, found)
max_row = ws1.max_row - 10
for cell in ws2.iter_rows(min_row=min_row, min_col=4, max_col=5, max_row=max_row):
if set((c.value for c in cell)) == {voornaam, achternaam}:
row_index = cell[0].row
print('Gevonden')
found = "Gevonden"
active_sheet = "ZONDAG"
for cell2 in ws2.iter_rows(min_row=cell[0].row, min_col=6, max_col=33, max_row=cell[0].row):
if voornaam is None:
voornaam = ''
break
if cell2[9].value == 'j':
cell2[27].value = 'al betaald'
else:
cell2[27].value = cell2[27].value
for cell3 in cell2:
if cell3.value is None:
cell3.value = "0"
print(f'besteling:\nMG {cell2[0].value}\nMGH {cell2[1].value}\nMK {cell2[2].value}\nMKH {cell2[3].value}\n'
f'PG {cell2[4].value}\nPGH {cell2[5].value}\nPK {cell2[6].value}\nPKH {cell2[7].value}\nBetaald: {cell2[9].value}\n\nTe betalen: {cell2[27].value}\n')
mg = cell2[0].value
mgh = cell2[1].value
mk = cell2[2].value
mkh = cell2[3].value
pg = cell2[4].value
pgh = cell2[5].value
pk = cell2[6].value
pkh = cell2[7].value
betaald = cell2[9].value
bedrag = cell2[27].value
dag = active_sheet
print(dag)
assign_var(mg, mgh, mk, mkh, pg, pgh, pk, pkh, betaald, dag, bedrag, found)
if row_index is not None:
print('{} {} is nummer {}'.format(voornaam, achternaam, row_index - 4))
print()
else:
print('{} {} niet gevonden in Range{}'.format(voornaam, achternaam, (min_row, max_row)))
def assign_var(mg, mgh, mk, mkh, pg, pgh, pk, pkh, betaald, dag, bedrag, found):
from GUI2 import Window
Window.assign(mg, mgh, mk, mkh, pg, pgh, pk, pkh, betaald, dag, bedrag, found)
解决方案
你的代码有很多问题。
您混淆了类和实例的概念
在您的第二个脚本中,您尝试访问classassign
的方法,但这是一个绑定方法。虽然该方法是该类的成员,但它旨在作为接收类实例作为第一个参数(“ ”属性)的方法。 Window
self
class Test(object):
def method(self):
print(self)
>>> test = Test()
>>> test.method()
<__main__.Test object at 0xb5d5ab0c>
>>> Test.method()
TypeError: unbound method method() must be called with Test instance as first argument (got nothing instead)
为了从实例调用该方法,您需要能够从第二个脚本访问该实例。稍后再谈。
有很多关于类和实例如何工作的文章,需要一些时间来搜索和研究它们。
global
尽量避免使用
使用全局变量可能会导致意外且难以检测的影响,最终您将面临比您想象的更多的问题。
特别是对于面向对象的编程,您必须了解每个对象及其成员(变量、函数等)的范围,以及它们如何在整个项目的层次结构中进行交换。
您还必须考虑全局变量的范围(在 Python 中,但不仅限于)仅存在于包含它的脚本中。您不能仅通过从后者访问x
文件中的全局变量。
根据类/实例概念,有很多关于此的文档。你可以从这里开始。A
B
global x
永远,永远不要编辑生成的代码pyuic
来创建你的程序
这是一个不幸的常见错误。
创建的文件pyuic
不打算作为开始编码的基础。虽然可以检查它们以获得关于如何在 Qt 中创建 GUI 的有用信息,但它们应该始终被视为资源,与图像或 json 文件不同。
主要原因是在某些时候您可能需要修改您创建的 UI,并且将新生成的py
文件与现有代码集成是不必要的辛苦,同时会导致数小时的编辑和头痛。
这些文件必须作为模块导入,并且只能按原样使用。
有多种方法可以使用该代码,但最常见和建议的是官方文档中解释的那些(特别是第三种方法,多重继承方法)。
请注意,该PyQt5.uic
模块还具有loadUi
能够直接加载.ui
文件的功能。这有其优点和缺点。虽然它可以避免每次修改 ui 时都需要重新生成资源文件,但它完全基于相对路径,并且在必须部署项目时可能很难检查。
我正在为您提供一些半伪代码,以了解如何实现您的需求。
main.py
:
from PyQt5 import QtWidgets
from ui_window import Ui_Window
from vind_gebruiker_zaterdag import start
class Window(QtWidgets.QMainWindow, Ui_Window):
def __init__(self):
super(Window, self).__init__()
self.setupUi(self)
self.search.clicked.connect(self.clicked)
def clicked(self):
result = start(self.vind_voornaam.text(), self.vind_achternaam.text())
mg = result[0]
mgh = result[1]
# ...
self.mg.setText(mg)
vind_gebruiker_zaterdag.py
:
# ...
def start(voornaam1, achternaam1):
voornaam = voornaam1
achternaam = achternaam1
active_sheet = ""
# ...
return mg, mgh, mk, mkh, pg, pgh, pk, pkh, betaald, dag, bedrag, found
请注意,由于我们不编辑 pyuic 生成的代码,您可以将两个文件(main 和 vind_gebruiker_zaterdag)集成到一个文件中。
推荐阅读
- unity3d - 透明着色器无法应用金属和平滑度
- python - Pandas 使用 for 循环连接数据帧
- c - 为什么 32 位操作系统最多支持 4 GB RAM
- node.js - 在 expressjs 中使用文件上传图像的工作表单
- fabricjs - fabricjs 以编程方式在移动浏览器上平移画布
- docker - 创建反应应用程序 + Gitlab CI + 数字海洋水滴 - 管道成功但 Docker 容器在之后立即被删除
- python - 图像识别中的预处理
- mvvm - 数据未在 Icommand 按钮单击时进入视图模型
- python - 删除 pd.DataFrame 中的最后一个单词
- c - fscanf 不保存行 - C