简体   繁体   English

pyqt5 坚持进口

[英]pyqt5 stuck with imports

I am making a GUI with pyqt5 and in 1 file I put the entire GUI application and in the other file i put the code for finding a name and surname in an excel spreadsheet.我正在用 pyqt5 制作一个 GUI,在 1 个文件中我放置了整个 GUI 应用程序,在另一个文件中我放置了用于在 Excel 电子表格中查找姓名和姓氏的代码。 In the GUI i want the user to enter a name and surname, then press the search button that activates the start() from file2.在 GUI 中,我希望用户输入姓名,然后按下从 file2 激活 start() 的搜索按钮。 in file 2 it searches a spreadsheet and takes data from it, the data needs to go to file1 and into a label of the GUI but it is always asking for a self parameter since it is a class needed for pyqt5.在文件 2 中,它搜索电子表格并从中获取数据,数据需要转到文件 1 并放入 GUI 的标签中,但它始终要求提供 self 参数,因为它是 pyqt5 所需的类。

file1:文件 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()

This is the file that takes a name and surname and searches for it in a spreadsheet and returns the other data in that row.该文件采用姓名和姓氏并在电子表格中搜索它并返回该行中的其他数据。

file2:文件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)

There are a lot of problems in your code.你的代码有很多问题。

You are confusing the concept of class and instance你混淆了类和实例的概念

In your second script, you're trying to access the assign method of the Window class , but that is a bound method.在您的第二个脚本中,您尝试访问Windowassign方法,但这是一个绑定方法。 While that method is a member of that class, it is intended as a method that receives a class instance as first argument (the " self " attribute).虽然该方法是该类的成员,但它旨在作为接收类实例作为第一个参数(“ 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)

In order to call that method from the instance, you'll need to be able to access that instance from the second script.为了从实例调用该方法,您需要能够从第二个脚本访问该实例。 More about that later.稍后再谈。
There's plenty of articles about how classes and instancies work, take some time to search and study them.有很多关于类和实例如何工作的文章,花一些时间来搜索和研究它们。

Avoid using global as much as possible尽量避免使用global

Using global variables can lead to unexpected and hard to detect effects, and in the end you'll face more problems than you'd think.使用全局变量会导致意想不到且难以检测的效果,最终您将面临比您想象的更多的问题。
Especially with object oriented programming, you must be aware about the scope of every object and its members (variables, functions, etc), and how they could be exchanged within the hierarchy of the whole project.尤其是在面向对象的编程中,您必须了解每个对象及其成员(变量、函数等)的范围,以及它们如何在整个项目的层次结构中进行交换。

You also have to consider that the scope of a global variable (in Python, but not only) exists only within the script that contains it.您还必须考虑全局变量的范围(在 Python 中,但不仅限于)仅存在于包含它的脚本中。 You can't access a global variable x in file A from file B just by doing global x from the latter.您不能仅通过从后者执行global x来从文件B访问文件A的全局变量x
As per the class/instance concepts, there's a lot of documentation about this.根据类/实例概念,有很多关于此的文档。 You can start from here .你可以从这里开始。

Never, NEVER edit the code generated from pyuic to create your programs永远不要编辑从pyuic生成的代码来创建你的程序

This is an unfortunately common mistake.这是一个不幸的常见错误。
The files pyuic creates are not intended as a basis to begin coding with. pyuic创建的文件不打算作为开始编码的基础。 While they can be inspected to get useful insight on how a GUI is created in Qt, they should always be treated as a resource , not unlike an image or a json file.虽然可以检查它们以获得有关如何在 Qt 中创建 GUI 的有用见解,但它们应始终被视为资源,与图像或 json 文件不同。

The main reason for this is that at some point you'll likely need to modify the UI you created, and integrating the new generated py file with the existing code is unnecessarily painstaking, while leading to hours of editing and headaches.这样做的主要原因是,在某些时候您可能需要修改您创建的 UI,并且将新生成的py文件与现有代码集成是不必要的麻烦,同时会导致数小时的编辑和头痛。

Those files must be imported as modules and only used as such.这些文件必须作为模块导入并仅用作模块。

There are various ways to use that code, but the most common and suggested are those explained in the official documentation (particularly the third method, the multiple inheritance method).有多种方法可以使用该代码,但最常见和建议的是官方文档中解释的那些(特别是第三种方法,多重继承方法)。

Note that the PyQt5.uic module also has the loadUi function, which is able to directly load an .ui file.注意PyQt5.uic模块也有loadUi函数,可以直接加载.ui文件。 This has its pros and cons.这有其优点和缺点。 While it can avoid the need to regenerate the resource files each time the ui is modified, it's completely relative-path-based, and that could be hard to inspect when your project has to be deployed.虽然它可以避免每次修改 ui 时都需要重新生成资源文件,但它完全基于相对路径,并且在必须部署项目时可能很难检查。


I'm providing you some semi-pseudo-code to understand how you can achieve what you need.我为您提供了一些半伪代码,以了解如何实现您的需求。

main.py : 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 : 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

Note that, since we are not editing the pyuic generated code, you could just integrate both files (main and vind_gebruiker_zaterdag) into a single one.请注意,由于我们没有编辑 pyuic 生成的代码,您可以将两个文件(main 和 vind_gebruiker_zaterdag)整合到一个文件中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM