pyqt5坚持进口

Posted

技术标签:

【中文标题】pyqt5坚持进口【英文标题】:pyqt5 stuck with imports 【发布时间】:2020-01-18 23:22:12 【问题描述】:

我正在使用 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)

【问题讨论】:

【参考方案1】:

你的代码有很多问题。

你混淆了类和实例的概念

在您的第二个脚本中,您尝试访问Window classassign 方法,但这是一个绑定 方法。虽然该方法是该类的 member,但它旨在作为接收类 instance 作为第一个参数(“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 中,但不仅限于)仅存在于包含它的脚本中。您无法通过从文件B 访问文件A 中的全局变量x,只需从后者执行global x。 根据类/实例概念,有很多关于此的文档。你可以从here开始。

绝不,绝不编辑从 pyuic 生成的代码来创建您的程序

这是一个不幸的常见错误。pyuic 创建的文件并不是开始编码的基础。虽然可以检查它们以获得关于如何在 Qt 中创建 GUI 的有用信息,但它们应始终被视为 资源,与图像或 json 文件不同。

这样做的主要原因是,在某些时候您可能需要修改您创建的 UI,并且将新生成的 py 文件与现有代码集成是不必要的辛苦,同时会导致数小时的编辑和头痛.

这些文件必须作为模块导入,并且只能作为模块使用。

有多种方法可以使用该代码,但最常见和建议的是official documentation 中解释的那些(特别是第三种方法,多重继承方法)。

注意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)集成到一个文件中。

【讨论】:

以上是关于pyqt5坚持进口的主要内容,如果未能解决你的问题,请参考以下文章

使用PyQt5创建时间轴

Pyqt5 & QML2 部署在 debian/mint (dev - ubuntu)

PyQt5 和 Django:如何使用 HTTP 请求(Multipart-form)上传图像?

010 坚持这事,无需刻意坚持 。

教义坚持+坚持=插入+插入?

坚持,再坚持---工作总结2