Textausgabe in Label ungewollt in geschweifter Klammer

Fragen zu Tkinter.
Antworten
MagicMarvin
User
Beiträge: 3
Registriert: Montag 4. Juli 2016, 18:10

Hey,
ich hab ein kleines Mini-Programm geschrieben, um Python und Tkinter mal ein bisschen kennenzulernen.
Dabei soll bei Betätigung eines Buttons in einem Label ein Satz erscheinen.
Dafür hab ich drei Listen erstellt, aus denen je ein Element zufällig ausgewählt wird.
Als Beispiel:
Aus liste1: Peter
Aus liste2: möchte
Aus liste3: einen Apfel

Das ganze klappt auch wie gewollt, nur werden die aus liste2 und liste3 ausgewählten Elemente immer in geschweiften Klammern ausgegeben.

Hier der Code:

Code: Alles auswählen

list1=('Gustav', 'Peter', 'Thomas')
list2=("will sofort", "hätte jetzt gerne", "hat mal wieder Bock auf", "möchte bitte", "bekommt endlich", "würde sich freuen über")
list3=("einen Apfel", "eine Birne", "einen Schluck Wasser")

import random
from tkinter import *
from tkinter import ttk

mainwin=Tk()
def Kommando():
    Satz.set((random.choice(list1), random.choice(list2), (random.choice(list3))))

Satz=StringVar()
label1=ttk.Label(mainwin, textvariable=Satz, width=50)
button1=ttk.Button(mainwin, text="Los geht's!", command=Kommando, width=20)

button1.grid()
label1.grid()
Vielleicht liegts am Code, vielleicht an irgendwas anderem,
Ich hoffe jemand kennt eine Lösung!

Gruß Marvin
Zuletzt geändert von Anonymous am Montag 4. Juli 2016, 20:37, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@MagicMarvin: Du musst der `set()`-Methode *eine* Zeichenkette übergeben, und nicht ein Tupel mit drei Zeichenketten.

`list` ist an sich schon ein schlechter Name, durch nummerieren wirds eher schlechter als besser, und wirklich ganz schlecht ist es wenn man dann noch nicht mal eine Liste an den Namen bindet. Namen sollten die Bedeutung des Wertes innerhalb des Programms wiederspiegeln und nicht den Typ. Und wenn man anfängt Nummern an Namen zu hängen, dann sollte man sich entweder *dringend* Gedanken um treffende Namen machen, oder man wollte eigentlich eine Datenstruktur statt einzelner Namen. Oft eine Liste. Einfach mal ”auf Vorrat” eine 1 an Namen zu hängen ist unsinnig.

Die Importe stehen üblicherweise am Anfang des Moduls, damit man dort schon sieht wovon das Modul abhängt.

Sternchenimporte vermeidet man, denn damit müllt man sich den Namensraum des importierenden Moduls voll. Es wird unübersichtlich und es besteht die Gefahr von Namenskollisionen.

Funktionen sollten nichts verwenden, ausser Konstanten, was nicht als Argument übergeben wurde. Auf `Satz` dürfte `Kommando` also nicht einfach so zugreifen. Das ginge auch gar nicht wenn das Hauptprogramm in einer Funktion stehen würde, wo es hingehört.
MagicMarvin
User
Beiträge: 3
Registriert: Montag 4. Juli 2016, 18:10

Danke für die Antwort!
Klar, das mit den Namen stimmt schon, aber bei drei Listen - oder eben Tupels (jetzt weiß ich auch, dass es sowas gibt...) - hält sich die Unübersichtlichkeit ja noch in Grenzen.

Macht Liste oder Tupel in diesem Beispiel einen Unterschied?

Ich muss zugeben, ich weiß noch nichtmal, was der Sternchenimport bedeutet... den hab ich einfach aus dem Internet übernommen.

Ist ".set()" dann hier einfach nicht die richtige Methode?

Was wäre denn eine sinnvolle Alternative?

Gruß Marvin
BlackJack

@MagicMarvin: `set()` ist in diesem Fall die richtige Methode, Du übergibst aber einen falschen Wert. Das muss wie gesagt *eine* Zeichenkette sein. Die musst Du halt aus den Einzelteilen erstellen, bevor Du sie übergeben kannst.

Letztlich würde ich aber auch nicht gerade mit GUIs anfangen solange die Grundlagen noch nicht sitzen. Also im Grunde alles bis einschliesslich objektorientierter Programmierung.
BlackJack

Code: Alles auswählen

import random
from functools import partial
import tkinter as tk
from tkinter import ttk

CHOICES = [
    ['Gustav', 'Peter', 'Thomas'],
    [
        'will sofort', 'hätte jetzt gerne', 'hat mal wieder Bock auf',
        'möchte bitte', 'bekommt endlich', 'würde sich freuen über',
    ],
    ['einen Apfel', 'eine Birne', 'einen Schluck Wasser'],
]
 
 
def create_sentence(label, choices):
    label['text'] = ' '.join(random.choice(cs) for cs in choices)


def main():
    root = tk.Tk()
    label = ttk.Label(root, width=50)
    label.pack()
    button = ttk.Button(
        root,
        text="Los geht's!",
        command=partial(create_sentence, label, CHOICES),
        width=20,
    )
    button.pack()
    root.mainloop()


if __name__ == '__main__':
    main()
MagicMarvin
User
Beiträge: 3
Registriert: Montag 4. Juli 2016, 18:10

oh wow, habs jetzt erst gesehen.
vielen dank! :)
Antworten