Photoimage

Fragen zu Tkinter.
Antworten
Lou Cyphr3
User
Beiträge: 59
Registriert: Donnerstag 6. Juli 2017, 00:04

hallo,

ich habe ein Problem mit dem imageloader von tkinter.

Ich wollte schlicht einen Text Button mit einem .png ersetzen. Mit dem Text hat der Button funktioniert. Jetzt bekomme ich beim ausführen einen Button ohne Bild und er führt auch das command nicht aus. Weiß jemand warum das so ist?

Im freien Test funktioniert es. Allerdings im Code nur so wie oben beschrieben.

Code: Alles auswählen

# läuft

class Test:
    def __init__(self, master):
        self.imagetest = PhotoImage(file="image.png")
        self.b = Button(master, image=self.imagetest, command=print_hello, width=150, height=150)
        self.b.grid(column=0,row=0,padx=275,pady=200)

# mit Text läuft auch

class Menu:
    def __init__(self):
        clear()
        self.Quiz = Button(root, text="Quiz", font=("Arial", 14), command=create_quiz, width=15, height=3)
        self.Quiz.grid(column=0,row=0,padx=275,pady=200)


# kein image/ kein command nach klicken
        
class Menu:
    def __init__(self):

        clear()
        self.imagetest = PhotoImage(file="image.png")
        self.Quiz = Button(root, image=self.imagetest, command=create_quiz, width=150, height=150)
        self.Quiz.grid(column=0,row=0,padx=275,pady=200)
Cours, camarade, le vieux monde est derrière toi!
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Der Codeausschnitt kann nicht das beobachtete Verhalten zeigen. Also brauchen wir den kompletten Code.
Der Aufruf von clear und das Benutzen von create_quiz sehen komisch aus, wenn man mit Klassen programmiert; da sollte ein `self` dabeistehen. Attribute schreibt man wie Variablennamen komplett klein.
Lou Cyphr3
User
Beiträge: 59
Registriert: Donnerstag 6. Juli 2017, 00:04

gibt noch einige ecken, aber hier schau mal rein.

Code: Alles auswählen

from tkinter import Button, Label, Tk, Text, PhotoImage, END
import random

root = Tk()
root.title("Quizzz")
root.geometry("800x700")
root.configure(bg = "#263D42")

#~~~~~ Fragen
questions = [["Wessen Mutter schwitzt nicht beim kacken?", "Merkels Mom", "Merkel selbst", "Söders Mom", "Chuck Norris Mom"],
             ["Wer oder was ist ein 'Spahn?", "Patient Zero", "Füllmaterial für Hamsterkäfig", "berühmte Trümmerfrau", " aktueller Gesundheitsminister"]]


def clear():
    line = root.grid_slaves()
    for i in line:
        i.destroy()

class Quiz:
    def __init__(self,quest):
        clear()
        self.questions = []
        for n in quest:
            self.questions.append(n)


        self.placeholder = []
        self.buttons = []
        self.right_ans = ""       # think about

        self.right_ans_button = Button(root, text="", font=("Arial", 14))     #think about


        self.next = Button(root, text="nächste Frage", font=("Arial", 14), command=self.question)
        self.lock = False
        self.right = 0
        self.number = 0
        self.Max = 2  # input button erstellen
        self.create_placeholder()
        self.create_buttons()
        self.question()

    def lock_it(self):
        self.lock = True       # lock funktion schreiben

    def question(self):
        self.next.grid(column=0, row=6, pady=5)

#~~~~~
        if len(self.questions) > 0 and self.number < self.Max:
            self.number += 1
            self.lock = False
            rand_num = random.randint(0, len(self.questions) - 1)
            quest_line = self.questions[rand_num][0]

#~~~~~ richtige Antwort zuweisen
            self.right_ans = self.questions[rand_num][-1]

#~~~~~ Antwortreihenfolge shufflen
            answers = []
            for i in range(1,5):
                answers.append(self.questions[rand_num][i])
            random.shuffle(answers)

#~~~~~ Antworten zuweisen

            self.placeholder[0] = answers[0]
            self.placeholder[1] = answers[1]
            self.placeholder[2] = answers[2]
            self.placeholder[3] = answers[3]

#~~~~~ Fragen in Label schreiben
            the_question = Text(root, font=("Arial", 14), width=40, height=2)
            the_question.insert(END, quest_line)
            the_question.grid(column=0, row=0, padx=80, pady=(75, 0))

#~~~~~ Fragen in Button schreiben
            self.buttons[0] = Button(root, text=self.placeholder[0], font=("Arial", 14), width=39, command = self.control1)
            self.buttons[1]  = Button(root, text=self.placeholder[1], font=("Arial", 14), width=39, command = self.control2)
            self.buttons[2]  = Button(root, text=self.placeholder[2], font=("Arial", 14), width=39, command = self.control3)
            self.buttons[3] = Button(root, text=self.placeholder[3], font=("Arial", 14), width=39, command = self.control4)

            self.buttons[0] .grid(column=0, row=1, pady=5)
            self.buttons[1] .grid(column=0, row=2, pady=5)
            self.buttons[2] .grid(column=0, row=3, pady=5)
            self.buttons[3] .grid(column=0, row=4, pady=5)

#~~~~~ richtige Antwort dem Button zuweisen

            if self.placeholder[0]== self.right_ans:
                self.right_ans_button = self.buttons[0]
            elif self.placeholder[1] == self.right_ans:
                self.right_ans_button = self.buttons[1]
            elif self.placeholder[2] == self.right_ans:
                self.right_ans_button = self.buttons[2]
            elif self.placeholder[3] == self.right_ans:
                self.right_ans_button = self.buttons[3]
            self.questions.pop(rand_num)

#~~~~~ Label mit Endergebnis auslegen
        else:
            clear()
            lb = Label(root, text="Du hast " + str(self.right) + " von " + str(self.Max) + " Fragen richtig beantwortet!", font=("Arial", 14))
            lb.grid(column=0,row=0,padx=120,pady=(170,15))
            to_menu = Button(root, text="zurück zum Start", font=("Arial", 14), command=create_menu)
            to_menu.grid(column=0,row=1)

    def create_buttons(self):

        for i in range(1, 5):
            answer_button = Button(root, text="", font=("Arial", 14), width=39)

            self.buttons.append(answer_button)

    def create_placeholder(self):
        for void in range(0, 5):
            placehold = None
            self.placeholder.append(placehold)

    def control1(self):
        if not self.lock:
            if self.right_ans != self.placeholder[0]:
                self.buttons[0].configure(bg="#CD0000")
            else:
                self.right += 1
            self.right_ans_button.configure(bg="green")
            self.lock_it()

    def control2(self):
        if  not self.lock:
            if self.right_ans != self.placeholder[1]:
                self.buttons[1].configure(bg="#CD0000")
            else:
                self.right += 1
            self.right_ans_button.configure(bg="green")
            self.lock_it()

    def control3(self):
        if  not self.lock:
            if self.right_ans != self.placeholder[2]:
                self.buttons[2] .configure(bg="#CD0000")
            else:
                self.right += 1
            self.right_ans_button.configure(bg="green")
            self.lock_it()

    def control4(self):
        if not self.lock:
            if self.right_ans != self.placeholder[3]:
                self.buttons[3] .configure(bg="#CD0000")
            else:
                self.right += 1
            self.right_ans_button.configure(bg="green")
            self.lock_it()



class Menu:
    def __init__(self):

        clear()
        self.Quiz = Button(root, text="das Quiz beginnen", font=("Arial", 14), command=create_quiz, width=15, height=3)
        self.Quiz.grid(column=0, row=0, padx=275, pady=200)

def create_menu():
   return Menu()

def create_quiz():
  return Quiz(questions)


#~~~~~ main

if __name__ == '__main__':

    create_menu()
    root.mainloop()
Cours, camarade, le vieux monde est derrière toi!
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@Lou Cyphr3: Du speicherst gar nicht das Menu-Exemplar und damit auch nicht das Bild, so dass es gleich wieder aus dem Speicher gelöscht wird. Damit funktioniert auch der Knopf nicht mehr.

Die Klasse an sich ist ziemlich sinnlos. Du benutzt fleißig globale Variablen, was den Code ziemlich undurchsichtig macht.
Kommentare werden sowei eingerückt, wie der umgebende Code.

`clear` sollte nicht existieren. Wenn man ein Fenster hat, und dort verschiedene Inhalte anzeigen will, packt man jede Seite in einen Frame und wechselt einfach diese Frames aus.
Zeile 23: n ist ein schlechter Name für eine Frage und Quest ist etwas anderes als Questions. Benutze richtige und sprechende Namen. Die ganze for-Schleife läst sich durch einen list-Aufruf ersetzen.
Zeile 27: das mit `placeholder` ist schon extrem unübersichtich. Erst wird eine leere Liste erstellt, ganz wo anders wird dann diese Liste mit Nones gefüllt, und wieder wo anders werden dann die einzelnen Einträge durch die "richtigen" Werte ersetzt. Warum nicht gleich die richtigen Werte an die Variable binden? Warum hat placeholder 5 Einträge?
Die vier Methoden control1..4 und die vielen Codewiederholungen für die Buttons sollte man alle zusammenfassen.

Mach eine Klasse, für eine Frage, die wird dann auch explizit mit einer Frage aufgerufen. Die Klasse erzeugt einen Frame, wo alle Buttons eingebaut werden
Dann eine Klasse, für den Start, auch wieder ein Frame.
Und eine Klasse für das Ende.
Außerdem gibt es eine Klasse für das Hauptprogramm, das dafür sorgt, dass die Frames in der richtigen Reihenfolge angezeigt werden.
Antworten