tkinter OOP, ich hab seit Tagen 'nen Hänger..

Fragen zu Tkinter.
Antworten
Milla

Morgen ihr Hübschen..
Funktionierender Code - nicht funktionierender Code..
Um Redundanzen zu vermeiden wollte ich umstellen - und hab 'nen Hänger..




Was -soweit fertig geschrieben- läuft:

Code: Alles auswählen

import tkinter as tk
from tkinter import *
from tkinter import font
import random
import sqlite3


class DBConnection():
    def __init__(self, host):
        self.connection = None
        self.host = host

    def __enter__(self):
        self.connection = sqlite3.connect(host)
        return self.connection

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.connection.commit()
        self.connection.close()

# create database
def createBase():
    try:
        with DBConnection('data.db') as connection:
            cursor = connection.cursor()
            cursor.execute('CREATE TABLE IF NOT EXISTS done(ergebnis integer primary key)')
    except:
        print('An error occured.')

# insert data into database
def insertBase():
    try:
        with DBConnection('data.db') as connection:
            cursor = connection.cursor()
            cursor.execute(f'INSERT INTO data VALUES(?)', (ergebnis))
    except:
        print('An error occured.')

# extracting data from table
def selectBase():
    try:
        with DBConnection('data.db') as connection:
            cursor = connection.cursor()
            cursor.execute('SELECT * FROM done WHERE name=?', (name))
    except:
        print('An error occured.')

def deleteBase():
    try:
        with DBConnection('data.db') as connection:
            cursor = connection.cursor()
            cursor.execute('DELETE * FROM done WHERE name=?', (name))
    except:
        print('An error occured.')


font = ('Helvetica', 14)
Font = ('Helvetica', 28)
FONT = ('Helvetica', 48)


class Maths4JoyApp(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        window = tk.Frame(self)
        window.pack(side='top', fill='both', expand = True)
        window.grid_rowconfigure(0, weight=1)
        window.grid_columnconfigure(0, weight=1)
        self.frames = {}
        for F in (MainWindow, AdditionWindow, SubtraktionWindow, MultiplikationWindow, DivisionWindow):
            frame = F(window, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky='NEWS')
        self.show_frame(MainWindow)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()


class MainWindow(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        welbutton = Button(self, width='45', height='3', text='Anmelden', bg='gray', fg='white', font=font, command=LoginWindow).place(x=220, y=32)
        addbutton = Button(self, width='20', height='5', text='Addition', bg='yellow', fg='blue', font=font, command=lambda :controller.show_frame(AdditionWindow)).place(x=220, y=130)
        subbutton = Button(self, width='20', height='5', text='Subtraktion', bg='green', fg='red', font=font, command=lambda :controller.show_frame(SubtraktionWindow)).place(x=495, y=130)
        mulbutton = Button(self, width='20', height='5', text='Multiplikation', bg='red', fg='green', font=font, command=lambda :controller.show_frame(MultiplikationWindow)).place(x=220, y=275)
        divbutton = Button(self, width='20', height='5', text='Division', bg='blue', fg='yellow', font=font, command=lambda :controller.show_frame(DivisionWindow)).place(x=495, y=275)
        savbutton = Button(self, width='45', height='3', text='Speichern', bg='gray', fg='white', font=font).place(x=220, y=420)



class AdditionWindow(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        def checkAdd():
            if control.get() != ergebnis:
                checkField.create_image(140, 135, anchor=CENTER, image=NOPE)
            elif control.get() == ergebnis:
                checkField.create_image(140, 135, anchor=CENTER, image=YES)
            else:
                checkField.create_image(140, 135, anchor=CENTER, image=LOGO)


        NOPE = PhotoImage(file='C:/Users/User/OneDrive/_GitHub/maths4joy/images/s_red.gif')
        LOGO = PhotoImage(file='C:/Users/User/OneDrive/_GitHub/maths4joy/images/wolfsw.gif')
        YES = PhotoImage(file='C:/Users/User/OneDrive/_GitHub/maths4joy/images/s_green.gif')
        operand = random.randint(1, 99999)
        operator = random.randint(1, 99999)
        ergebnis = operand + operator
        checkField = Canvas(self, width=265, height=267, bg='silver')
        checkField.place(x=630, y=260)
        backbutton = Button(self, width=10, height=1, text='Menue', bg='red',fg='blue', font=font, command=lambda :controller.show_frame(MainWindow)).place(x=10, y=10)
        repeatbutton = Button(self, width=20, height=1, text='neue Aufgabe', bg='green',fg='yellow', font=font, command=lambda :controller.show_frame(createNew)).place(x=365, y=10)
        skipbutton = Button(self, width=10, height=1, text='Subtraktion', bg='blue',fg='red', font=font).place(x=820, y=10)
        operandFeld = Text(self, width=5, height=1, bg='white', fg='blue', font=FONT)
        operandFeld.place(x=75, y=125)
        operandFeld.insert(INSERT, operand)
        plusSign = Label(self, width=1, height=1, text='+', bg='silver', fg='red', font=FONT).place(x=270, y=125)
        operatorFeld = Text(self, width=5, height=1, bg='white', fg='blue', font=FONT)
        operatorFeld.place(x=325, y=125)
        operatorFeld.insert(INSERT, operator)
        equalSign = Label(self, width=1, height=1, text='=', bg='silver', fg='green', font=FONT).place(x=520, y=125)
        control = IntVar()
        eingabe = Entry(self, width=6, bg='white', fg='blue', font=FONT, textvariable=control).place(x=575, y=125)
        sendButton = Button(self, width=3, height=1, relief=RAISED, text='OK', bg='khaki', fg='black', font=Font, command=checkAdd).place(x=825, y=127)
        nebenlabel = Label(self, text='Mein Platz für Nebenrechnungen', width=39, bg='orange', fg='blue').place(x=10, y=260)
        nebenrechnung = Text(self, width=25, height=11, bg='white', fg="orange", font=font).place(x=10, y=285)


class SubtraktionWindow(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        def checkMinus():
            if control.get() != ergebnis:
                checkField.create_image(140, 135, anchor=CENTER, image=NOPE)
            elif control.get() == ergebnis:
                checkField.create_image(140, 135, anchor=CENTER, image=YES)
            else:
                checkField.create_image(140, 135, anchor=CENTER, image=LOGO)
        NOPE = PhotoImage(file='C:/Users/User/OneDrive/_GitHub/maths4joy/images/s_red.gif')
        LOGO = PhotoImage(file='C:/Users/User/OneDrive/_GitHub/maths4joy/images/wolfsw.gif')
        YES = PhotoImage(file='C:/Users/User/OneDrive/_GitHub/maths4joy/images/s_green.gif')
        operand = random.randint(1, 99999)
        operator = random.randint(1, 9999)
        ergebnis = operand - operator
        checkField = Canvas(self, width=265, height=267, bg='silver')
        checkField.place(x=630, y=260)
        backbutton = Button(self, width=10, height=1, text='Menue', bg='red',fg='blue', font=font, command=lambda :controller.show_frame(MainWindow)).place(x=10, y=10)
        repeatbutton = Button(self, width=20, height=1, text='neue Aufgabe', bg='green',fg='yellow', font=font, command=lambda :controller.show_frame(SubtraktionWindow)).place(x=365, y=10)
        skipbutton = Button(self, width=10, height=1, text='Subtraktion', bg='blue',fg='red', font=font).place(x=820, y=10)
        operandFeld = Text(self, width=5, height=1, bg='white', fg='blue', font=FONT)
        operandFeld.place(x=75, y=125)
        operandFeld.insert(INSERT, operand)
        minusSign = Label(self, width=1, height=1, text='-', bg='silver', fg='red', font=FONT).place(x=270, y=125)
        operatorFeld = Text(self, width=5, height=1, bg='white', fg='blue', font=FONT)
        operatorFeld.place(x=325, y=125)
        operatorFeld.insert(INSERT, operator)
        equalSign = Label(self, width=1, height=1, text='=', bg='silver', fg='green', font=FONT).place(x=520, y=125)
        control = IntVar()
        eingabe = Entry(self, width=6, bg='white', fg='blue', font=FONT, textvariable=control).place(x=575, y=125)
        sendButton = Button(self, width=3, height=1, relief=RAISED, text='OK', bg='khaki', fg='black', font=Font, command=checkMinus).place(x=825, y=127)
        nebenlabel = Label(self, text='Mein Platz für Nebenrechnungen', width=39, bg='orange', fg='blue').place(x=10, y=260)
        nebenrechnung = Text(self, width=25, height=11, bg='white', fg="orange", font=font).place(x=10, y=285)



class MultiplikationWindow(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        def checkMulti():
            if control.get() != ergebnis:
                checkField.create_image(140, 135, anchor=CENTER, image=NOPE)
            elif control.get() == ergebnis:
                checkField.create_image(140, 135, anchor=CENTER, image=YES)
            else:
                checkField.create_image(140, 135, anchor=CENTER, image=LOGO)

        NOPE = PhotoImage(file='C:/Users/User/OneDrive/_GitHub/maths4joy/images/s_red.gif')
        LOGO = PhotoImage(file='C:/Users/User/OneDrive/_GitHub/maths4joy/images/wolfsw.gif')
        YES = PhotoImage(file='C:/Users/User/OneDrive/_GitHub/maths4joy/images/s_green.gif')
        operand = random.randint(1, 99999)
        operator = random.randint(1, 9999)
        ergebnis = operand * operator
        checkField = Canvas(self, width=265, height=267, bg='silver')
        checkField.place(x=630, y=260)
        backbutton = Button(self, width=10, height=1, text='Menue', bg='red',fg='blue', font=font, command=lambda :controller.show_frame(MainWindow)).place(x=10, y=10)

        skipbutton = Button(self, width=10, height=1, text='Subtraktion', bg='blue',fg='red', font=font).place(x=820, y=10)
        operandFeld = Text(self, width=5, height=1, bg='white', fg='blue', font=FONT)
        operandFeld.place(x=75, y=125)
        operandFeld.insert(END, operand)
        multiSign = Label(self, width=1, height=1, text='x', bg='silver', fg='red', font=FONT).place(x=270, y=125)
        operatorFeld = Text(self, width=5, height=1, bg='white', fg='blue', font=FONT)
        operatorFeld.place(x=325, y=125)
        operatorFeld.insert(END, operator)
        equalSign = Label(self, width=1, height=1, text='=', bg='silver', fg='green', font=FONT).place(x=520, y=125)
        control = IntVar()
        eingabe = Entry(self, width=6, bg='white', fg='blue', font=FONT, textvariable=control).place(x=575, y=125)
        sendButton = Button(self, width=3, height=1, relief=RAISED, text='OK', bg='khaki', fg='black', font=Font, command=checkMulti).place(x=825, y=127)
        nebenlabel = Label(self, text='Mein Platz für Nebenrechnungen', width=39, bg='orange', fg='blue').place(x=10, y=260)
        nebenrechnung = Text(self, width=25, height=11, bg='white', fg="orange", font=font).place(x=10, y=285)

        def fresh_frame():
            operandFeld.delete(1.0, END)
            operatorFeld.delete(1.0, END)
            operand = random.randint(1, 99999)
            operator = random.randint(1, 9999)
            operandFeld.insert(INSERT, operand)
            operatorFeld.insert(INSERT, operator)
        repeatbutton = Button(self, width=20, height=1, text='neue Aufgabe', bg='green',fg='yellow', font=font, command=fresh_frame).place(x=365, y=10)

class DivisionWindow(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        def checkDivide():
            if control.get() != ergebnis:
                checkField.create_image(140, 135, anchor=CENTER, image=NOPE)
            elif control.get() == ergebnis:
                checkField.create_image(140, 135, anchor=CENTER, image=YES)
            else:
                checkField.create_image(140, 135, anchor=CENTER, image=LOGO)

        class buildNums():
            num1 = random.randint(1, 99999)
            num2 = random.randint(1, 9999)
            while num1 % num2 != 0:
                num1 = random.randint(1, 99999)
                num2 = random.randint(1, 9999)
                
        operand = buildNums.num1
        operator = buildNums.num2
        ergebnis = operand / operator
        NOPE = PhotoImage(file='C:/Users/User/OneDrive/_GitHub/maths4joy/images/s_red.gif')
        LOGO = PhotoImage(file='C:/Users/User/OneDrive/_GitHub/maths4joy/images/wolfsw.gif')
        YES = PhotoImage(file='C:/Users/User/OneDrive/_GitHub/maths4joy/images/s_green.gif')
        checkField = Canvas(self, width=265, height=267, bg='silver')
        checkField.place(x=630, y=260)
        backbutton = Button(self, width=10, height=1, text='Menue', bg='red',fg='blue', font=font, command=lambda :controller.show_frame(MainWindow)).place(x=10, y=10)
        repeatbutton = Button(self, width=20, height=1, text='neue Aufgabe', bg='green',fg='yellow', font=font, command=lambda :controller.show_frame(buildNums)).place(x=365, y=10)
        skipbutton = Button(self, width=10, height=1, text='Subtraktion', bg='blue',fg='red', font=font).place(x=820, y=10)
        operandFeld = Text(self, width=5, height=1, bg='white', fg='blue', font=FONT)
        operandFeld.place(x=75, y=125)
        operandFeld.insert(INSERT, operand)
        divideSign = Label(self, width=1, height=1, text=':', bg='silver', fg='red', font=FONT).place(x=270, y=125)
        operatorFeld = Text(self, width=5, height=1, bg='white', fg='blue', font=FONT)
        operatorFeld.place(x=325, y=125)
        operatorFeld.insert(INSERT, operator)
        equalSign = Label(self, width=1, height=1, text='=', bg='silver', fg='green', font=FONT).place(x=520, y=125)
        control = IntVar()
        eingabe = Entry(self, width=6, bg='white', fg='blue', font=FONT, textvariable=control).place(x=575, y=125)
        sendButton = Button(self, width=3, height=1, relief=RAISED, text='OK', bg='khaki', fg='black', font=Font, command=checkDivide).place(x=825, y=127)
        nebenlabel = Label(self, text='Mein Platz für Nebenrechnungen', width=39, bg='orange', fg='blue').place(x=10, y=260)
        nebenrechnung = Text(self, width=25, height=11, bg='white', fg="orange", font=font).place(x=10, y=285)


class LoginWindow(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        login = self.login = tk.Toplevel()
        login.title('LogIn')
        login.geometry('320x180+66+33')
        login.grid_rowconfigure(0, weight=1)
        login.grid_columnconfigure(0, weight=1)
        NameL = Label(self, text='Anmeldename: ').pack()
        Name = IntVar()
        User = Entry(login, text='Anmeldename', textvariable=Name).place(x=175, y=55)
        PWL = Label(self, text='Passwort: ').place(x=50, y=75)
        PW = IntVar()
        Data = Entry(login, text='Passwort', textvariable=PW).place(x=175, y=75)
        LogButton = Button(login, text='Anmelden',).grid(row=5, column=0, sticky='W')
        CreaButton = Button(login, text='Registrieren').grid(row=5, column=1, sticky='E')

app = Maths4JoyApp()
app.title('maths4Joy')
app.geometry('960x540+200+100')
app.configure(bg='silver')
app.resizable(0, 0)

myMenu = Menu(app)
myMenu.add_command(label='Meine Ergebnisse')
myMenu.add_command(label='Ende', command=app.quit)
myMenu.add_command(label='Löschen')
app.config(menu=myMenu)

app.mainloop()
..was zwar startet, aber nicht die methods ausführt..

Code: Alles auswählen

import tkinter as tk
from tkinter import *
from tkinter import font
import random
# setting up fonts S, M, L
font = ('fontetica', 14)
Font = ('fontetica', 28)
FONT = ('fontetice', 48)


class Maths4JoyApp(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        window = tk.Frame(self)
        window.pack(side='top', fill='both', expand = True)
        window.grid_rowconfigure(0, weight=1)
        window.grid_columnconfigure(0, weight=1)
        self.frames = {}
        for F in (MainWindow, OperationWindow):
            frame = F(window, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky='NEWS')
        self.show_frame(MainWindow)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()


class MainWindow(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        welbutton = Button(self, width='45', height='3', text='Anmelden', bg='gray', fg='white', font=font, command=LoginWindow).place(x=220, y=32)
        addition = Button(self, width='20', height='5', text='Addition', bg='yellow', fg='blue', font=font, command=lambda : controller.show_frame(OperationWindow)).place(x=220, y=130)
        subtraction = Button(self, width='20', height='5', text='subtraction', bg='green', fg='red', font=font, command=lambda :controller.show_frame(OperationWindow)).place(x=495, y=130)
        multiplication = Button(self, width='20', height='5', text='Multiplikation', bg='red', fg='green', font=font, command=lambda :controller.show_frame(OperationWindow)).place(x=220, y=275)
        division = Button(self, width='20', height='5', text='Division', bg='blue', fg='yellow', font=font, command=lambda :controller.show_frame(OperationWindow)).place(x=495, y=275)
        savbutton = Button(self, width='45', height='3', text='Speichern', bg='gray', fg='white', font=font).place(x=220, y=420)


class OperationWindow(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        NOPE = PhotoImage(file='C:/Users/User/OneDrive/_GitHub/maths4joy/images/s_red.gif')
        LOGO = PhotoImage(file='C:/Users/User/OneDrive/_GitHub/maths4joy/images/wolfsw.gif')
        YES = PhotoImage(file='C:/Users/User/OneDrive/_GitHub/maths4joy/images/s_green.gif')

        def addition(self):
            sign = Label(width=1, height=1, text='+', bg='silver', fg='red', font=FONT).place(x=270, y=125)
            num1 = random.randint(1, 99999)
            num2 = random.randint(1, 99999)
            num3 = (num1 + num2)
            return (sign, num1, num2, num3)

        def subtraction(self):
            sign = Label(width=1, height=1, text='-', bg='silver', fg='red', font=FONT).place(x=270, y=125)
            num1 = random.randint(1, 99999)
            num2 = random.randint(1, 99999)
            if num1 < num2:
                num1 = random.randint(1, 99999)
                num2 = random.randint(1, 99999)
                num3 = (num1 - num2)
            return num1, num2, num3

        def multiplication(self):
            sign = Label(width=1, height=1, text='x', bg='silver', fg='red', font=FONT).place(x=270, y=125)
            num1 = random.randint(1, 99999)
            num2 = random.randint(1, 999)
            num3 = (num1 * num2)
            return num1, num2, num3

        def division(self):
            sign = Label(width=1, height=1, text=':', bg='silver', fg='red', font=FONT).place(x=270, y=125)
            while num1 % num2 != 0:
                num1 = random.randint(1, 99999)
                num2 = random.randint(1, 9999)
                num3 = (num1 / num2)
            return num1, num2, num3

        operand = num1.get()
        operator = num2.get()
        result = num3.get()

        def checkReturn():
            if control.get() != result.get():
                checkField.create_image(140, 135, anchor=CENTER, image=NOPE)
            elif control.get() == result.get():
                checkField.create_image(140, 135, anchor=CENTER, image=YES)
            else:
                checkField.create_image(140, 135, anchor=CENTER, image=LOGO)

        checkField = Canvas(self, width=265, height=267, bg='silver')
        checkField.place(x=630, y=260)
        backbutton = Button(self, width=10, height=1, text='Menue', bg='red',fg='blue', font=font, command=lambda :controller.show_frame(MainWindow)).place(x=10, y=10)
        skipbutton = Button(self, width=10, height=1, text='subtraction', bg='blue',fg='red', font=font).place(x=820, y=10)
        operandFeld = Text(self, width=5, height=1, bg='white', fg='blue', font=FONT)
        operandFeld.place(x=75, y=125)
        operandFeld.insert(END, operand)
        operatorFeld = Text(self, width=5, height=1, bg='white', fg='blue', font=FONT)
        operatorFeld.place(x=325, y=125)
        operatorFeld.insert(END, operator)
        equalSign = Label(self, width=1, height=1, text='=', bg='silver', fg='green', font=FONT).place(x=520, y=125)
        control = IntVar()
        eingabe = Entry(self, width=6, bg='white', fg='blue', font=FONT, textvariable=control).place(x=575, y=125)
        sendButton = Button(self, width=3, height=1, relief=RAISED, text='OK', bg='khaki', fg='black', font=Font, command=checkReturn).place(x=825, y=127)
        nebenlabel = Label(self, text='Mein Platz für Nebenrechnungen', width=39, bg='orange', fg='blue').place(x=10, y=260)
        nebenrechnung = Text(self, width=25, height=11, bg='white', fg="orange", font=font).place(x=10, y=285)

        def fresh_frame():
            operandFeld.delete(1.0, END)
            operatorFeld.delete(1.0, END)
            operand = random.randint(1, 99999)
            operator = random.randint(1, 9999)
            operandFeld.insert(END, operand)
            operatorFeld.insert(END, operator)
        repeatbutton = Button(self, width=20, height=1, text='neue Aufgabe', bg='green',fg='yellow', font=font, command=fresh_frame).place(x=365, y=10)



class LoginWindow(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        login = self.login = tk.Toplevel()
        login.title('LogIn')
        login.geometry('320x180+66+33')
        login.grid_rowconfigure(0, weight=1)
        login.grid_columnconfigure(0, weight=1)
        NameL = Label(self, text='Anmeldename: ').pack()
        Name = IntVar()
        User = Entry(login, text='Anmeldename', textvariable=Name).place(x=175, y=55)
        PWL = Label(self, text='Passwort: ').place(x=50, y=75)
        PW = IntVar()
        Data = Entry(login, text='Passwort', textvariable=PW).place(x=175, y=75)
        LogButton = Button(login, text='Anmelden',).grid(row=5, column=0, sticky='W')
        CreaButton = Button(login, text='Registrieren').grid(row=5, column=1, sticky='E')


app = Maths4JoyApp()
app.title('maths4Joy')
app.geometry('960x540+200+100')
app.configure(bg='silver')
app.resizable(0, 0)

myMenu = Menu(app)
myMenu.add_command(label='Meine resultse')
myMenu.add_command(label='Ende', command=app.quit)
myMenu.add_command(label='Löschen')
app.config(menu=myMenu)

app.mainloop()
#--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------#
# Nachtrag: ..gerade gemerkt - läuft nicht (deuglyfied), liegt daran, dass.. ------------------------------------------------------------------------------------------------------------------- #
# 1. ..hatte ich erfolglos versucht die Buttons mit einem "command=lambda :controller.show_frame(OperationWindow.~method)" zu belegen ------ #
# 2. ..hatte ich über den def's die nums definiert als num1 = {} / [] / () num2 = ... ----------------------------------------------------------------------------------------------------------#
#--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------#

Für Anregungen wäre ich sehr dankbar.
Schönes Wochenende!
Benutzeravatar
__blackjack__
User
Beiträge: 13080
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Milla: Was beim drüberschauen als ertses aufgefallen ist, das Du Namen an `None` bindest – `place()` gibt nämlich nicht das Objekt zurück auf dem es aufgerufen wurde, sondern `None`.

Womit wir beim zweiten Problem wären: `place()`. Das sieht auf dem System auf dem das entworfen wurde so aus wie der Autor das wollte, aber wenn sich etwas ändert (Schriftgrösse(n), Monitorauflösung, …) dann passen die Pixelgenauen platzierungen nicht mehr. Ich habe schon GUIs gesehen die dadurch unbenutzbar wurden, weil man wichtige Sachen nicht mehr sehen konnte.

Mir ist da ehrlich gesagt nicht so ganz klar was das `OperationsWindows` letztlich werden sollte. Auf jeden Fall werden die lokalen Funktionen für die Rechenarten nirgends aufgerufen. Dann haben die nicht alle die gleiche API, obwohl sie das wahrscheinlich sollten.

Und letztlich sollte man auch keine lokalen Funktionen verwenden. Die sind nur ganz selten wirklich nötig. Innerhalb einer Methode meistens noch seltener, denn da braucht man seltener ein Closure, weil man ja schon zugriff auf das Objekt hat über das die Methode ja bereits ein Closure ist.

Wenn Du etwas zeigst was nicht funktioniert, dann wäre es gut wenn Du sagst *was* nicht funktioniert. Und bei Ausnahmen die 1:1 samt Traceback zeigen. Ich vermute mal das gibt einen `NameError` weil in `OperationWindow.__init__()` der Name `num1` in Zeile 83 nicht definiert ist (`num2` und `num3` auch nicht).

`LoginWindow` ist kaputt. Das erbt von `tk.Tk` rufst dann aber die `__init__()` von `tk.Frame` mit sich selbst auf. Das sollte wohl von `tk.Frame` erben. Da ist in der `__init__()` dann auch ziemlich verquer welche Widgets wo dargestellt werden sollen. Die Hälfte hat als `master` das Objekt selbst, die andere das neu erstellte `Toplevel`. Und `tk.IntVar` für Name und Passwort ist wohl auch nicht richtig‽

Mit dem ”Controller” käme man wohl am besten aus wenn man die Operationsklassen nicht versucht in eine zu stecken, sondern die gemeinsamkeiten der Operationen in eine zusätzliche Basisklasse verschiebt. Dann hast Du selbst mal was mit Vererbung gemacht.

Besser wäre es aber wirklich nur eine Klasse für das Operationsfenster zu haben und den Auswahlcode flexibler zu gestalten. Im Moment sind ja Klassen der Schlüssel um die angezeigte Seite zu wählen, was zwangsläufig bedeutet, das man dort pro Seite eine Klasse haben muss und nicht beispielsweise eine parametrisierte Klasse mehr als einmal instanziiert werden kann mit Argumenten welche die jeweilige Darstellung und/oder Funktionsweise beeinflussen.

Was man auch machen könnte wäre nur eine Klasse und damit nur eine Seite für die Rechenoperationen und das man nicht nur auf diese Seite umschalten muss, sondern der Seite dann noch zusätzlich sagen muss welche Rechnungsart sie anzeigen soll.

Da könnte/sollte man auch mal die Programmlogik, so einfach sie auch sein mag, von der GUI trennen. So eine Rechenart hat ja mindestens ein Rechensymbol und eine Funktion die die Aufgabe erstellt. Zugegebenermassen etwas wenig um es in eine Klasse zusammen zu fassen. Ich würde da wahrscheinlich einen simplen Dekorator für schreiben, der das Rechensymbol einfach als Attribut an die Funktion pappt. Das kann man dann später immer noch zu einer Klasse aufbohren.

Sonst so das übliche: Sternchen-Importe sind Böse™, auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert, das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase).

Einbuchstabige Namen sind selten gute Namen. Namen mit kryptischen Abkürzungen sind nie gute Namen.

Bei der Subtraktion verstehe ich das ``if`` nicht so richtig – beim zweiten Versuch Zahlen zu finden kann es doch wieder passieren das das Ergebnis negativ is‽ Theoretisch müsste da wie bei der Division eine Schleife stehen. Aber in der Praxis will man das bei beiden nicht in einer Schleife machen. Wenn das Ergebnis bei der Subtraktion negativ wäre, tauscht man einfach beide Operanden. Und bei der Division würfelt man nicht die beiden Operanden aus, sondern einen Operanden und das Ergebnis – woraus man dann per Multiplikation den anderen Operanden ausrechnet.

`division()` wäre so sowieso nicht gelaufen, weil `num1` und `num2` vor Eintritt in die Schleife gar nicht definiert sind, in der Schleifenbedingung aber benutzt werden. Python hat keine nachprüfende Schleife, also muss man für so etwas eine ”Endlosschleife” (``while True:``) schreiben wo man am Ende dann mit einem ``if`` die Abbruchbedingung prüft und gegebenenfalls mit ``break`` die Schleife abbricht.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Milla

Wow.. was für 'ne ausführliche Antwort..
Danke dafür erst einmal.

Mein Fazit daraus: ..ich mach' weiter Bildchen
und lass das programmieren Euren eins.

Gut: Umschulungsmaßnahmenabbruch.
Danke für die Inspiration.

bye.
Benutzeravatar
__blackjack__
User
Beiträge: 13080
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Milla: Da waren einige Sachen dabei die relativ einfach geändert werden können. Und um die Redundanzen in den vier ”Fenstern” mit den Operationen zu vermeiden, ist das einfachste erst einmal eine Basisklasse mit dem Code heraus zu ziehen der von allen vier geteilt wird. Das ist vier Klassen ohne GUI-Komponenten für die Rechenarten und eine Klasse die dann so eine Rechenart als Argument bekommt, zu ändern ist an sich auch nicht schwer(er) und wäre sauberer, aber dann funktioniert der ”Controller” so nicht mehr der eine Klasse pro umschaltbarer Seite im Fenster verlangt. Da wäre dann die Frage wie gut Du den Code verstanden hast, denn ich vermute der ist nicht von Dir, denn ich bin mir ziemlich sicher, dass ich den schon mal vorher gesehen habe.

Programmieren lernen dauert halt ein bisschen, und GUI ist für den Anfang ziemlich hart, weil man da im Grunde ”alles” andere zu braucht, also insbesondere objektorientierte Programmierung.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten