简体   繁体   中英

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. In the GUI i want the user to enter a name and surname, then press the search button that activates the start() from file2. 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.

file1:

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:

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. 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).

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

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. You can't access a global variable x in file A from file B just by doing global x from the latter.
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

This is an unfortunately common mistake.
The files pyuic creates are not intended as a basis to begin coding with. 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.

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.

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. 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.


I'm providing you some semi-pseudo-code to understand how you can achieve what you need.

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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