Tipps bzgl. Funktionen bei GUI

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
ichbins
User
Beiträge: 40
Registriert: Samstag 5. September 2020, 07:07

Hallo

es wurde mir empfohlen bei tkinter grid statt place zu verwenden. Ich bräuchte bei einem Entry Widget links 50pixel, oben 50pixel, rechts 10pixel und unten 70pixel. Ich habe nur padx und pady gefunden. Das bezieht sich aber auf beide Seiten horizontal und vertikal. Gibt es da eine andere Lösung.

Danke!

LG
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

@ichbins: wenn Du pixelgenau Abstände brauchst, dann hast Du da schon einen Fehler im Design. Warum denkst Du, brauchst Du das?
ichbins
User
Beiträge: 40
Registriert: Samstag 5. September 2020, 07:07

Ich wollte nur Label und Entry Widgets, die nebeneinander sind, einrücken. Und darunter brauche ich Abstand. Somit links und oben ist der gleiche Abstand und rechts und darunter sind andere Abstände.

Vermutlich kann ich es lösen indem ich row und column (oben und links) leer lasse und erst ab row=1 und column=1 anfange und row=2 wieder leer lasse
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

ichbins
User
Beiträge: 40
Registriert: Samstag 5. September 2020, 07:07

Danke für den Tipp. Ich finde aber schon dass grid viel umständlicher ist als place bis ich das positioniere mit padx, pady, sticky usw.

Andere Frage: Wie kann ich Canvas programmieren damit es wie ein Button funktioniert. Ich habe nur fill und activefill gefunden. Es soll aber nach Button-1 pressed wieder der alte Zustand sein.

Danke!

Code: Alles auswählen

self.punkte=[0,0,50,0,75,20,50,40,0,40]
        self.pfeil=tk.Canvas(self.window)
        self.pfeil.create_polygon(self.punkte)#, activefill='white', outline='black', width=5)
        self.pfeil.grid(row=17, column=5, sticky=tk.NW)
        self.pfeil.bind('<Button-1>', self.canvas_button)
        self.window.bind('<Return>', self.canvas_button)


    def canvas_button(self, event):
        self.pfeil.create_polygon(self.punkte, activefill='blue')
ichbins
User
Beiträge: 40
Registriert: Samstag 5. September 2020, 07:07

Ich habe das jetzt auf diese Art gelöst aber es funktioniert nicht von der Zeit her. Manchmal muss man gedrückt bleiben, dann ist der Canvas Widget nur ganz kurz weiß usw. Gibt es da noch eine andere Möglichkeit das zu lösen?

Danke!

Code: Alles auswählen

        self.punkte=[0,0,50,0,75,20,50,40,0,40]
        self.pfeil=tk.Canvas(self.window)
        self.pfeil.create_polygon(self.punkte)#, activefill='white', outline='black', width=5)
        self.pfeil.grid(row=17, column=5, sticky=tk.NW)
        self.pfeil.bind('<Button-1>', self.senden)
        self.pfeil.bind('<ButtonRelease>', self.off)
        self.window.bind('<Return>', self.send)


    def senden(self, event):
        self.pfeil.after(150, self.on)
        self.off

    
    def on(self):
        self.pfeil.create_polygon(self.punkte, fill='white', outline='black', width=5 )
        
    def off(self, event):
        self.pfeil.create_polygon(self.punkte, fill='black')
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

Ich kam mit den Code-Fragmenten wenig anfangen. Ständig neue Polygone zu erzeugen ist jedenfalls falsch. Die werden alle nacheinander übereinander gezeichnet.
ichbins
User
Beiträge: 40
Registriert: Samstag 5. September 2020, 07:07

Es ist das einzige Polygon dass ein Pfeil ist und die Funktion eines Buttons hat. Wenn ich auf den Pfeil click soll es die Funktion "senden" ausführen. Dieses Polygon führt die Funktion senden aus jedoch man kann nicht erkennen dass es gedrückt wurde bzw. bei after() kann man erkennen dass es gedrückt wurde jedoch passen die Zeiten nicht wie beim Button.
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@ichbins: In `on()` wird jedes mal ein neues, zusätzliches Polygon gezeichnet, und in `off()` wird jedes mal ein neues, zusätzliches Polygon gezeichnet. Das ist keine Pixelgrafik wo ein neues Zeichnen einfach die gleichen Pixel mit anderen Werten belegt. Das ist Vektorgrafik in der Du immer neue Grafikobjekte erstellst die auch immer alle immer wieder übereinander gezeichnet werden.

Man erstellt einmal ein Polygon und ändert dann nur dessen Eigenschaften.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
ichbins
User
Beiträge: 40
Registriert: Samstag 5. September 2020, 07:07

Ich habe es jetzt mit itemconfig geändert und es funktioniert. Danke.

Wie kann man eigentlich beim Grid von Column1 bis Column 4, 10 Entries einfügen. Ist es eigentlich möglich in ein Column mehrere Entries einzufügen.

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

@ichbins: In Spalten 1 bis 4 bekommt man 10 Eingabefelder in dem man die auf mehrere Zeilen verteilt.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
ichbins
User
Beiträge: 40
Registriert: Samstag 5. September 2020, 07:07

Ich habe es so probiert aber es funktioniert nicht. Wie hast du das genau gemeint.

Mit sys.stdout.flush() leer ich den Puffer damit nicht mehrere Fenster geöffnet werden beim Start falls das Programm nicht funktioniert hat. Ist das richtig?

Code: Alles auswählen

        for column in range(0,9):
            entry=tk.Entry(self.window, width=4)
            entry.grid(row=16, column=[1][column], pady=(4,0))
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@ichbins: Der Ausdruck bei `column` macht keinen Sinn, weil der ganz offensichtlich nur funktioniert wenn `column` den Wert 0 hat. Wenn man nur 4 Spalten in der Breite haben will, muss man 10 Eingabeelemente halt auch auf verschiedene Zeilen verteilen. Also zwei Zeilen mit 4 Eingabeelementen und eine mit 2 Eingabeelementen um am Ende auf 10 zu kommen. Oder man tritt mal einen Schritt zurück und schaut ob man das ganze nicht anders organisieren kann/will.

`sys.stdout.flush()` hat mit GUI und Fenstern überhaupt nichts zu tun. Das sorgt dafür, das Daten die eventuell noch im Puffer der Standardausgabe liegen, nach draussen geschrieben werden. Die Standardausgabe ist das wo beispielsweise `print()` normalerweise hin schreibt.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
ichbins
User
Beiträge: 40
Registriert: Samstag 5. September 2020, 07:07

Die 10 Entries sollen nicht untereinander sein bzw. 4,4,2, sondern alle waagrecht nebeneinander. Und ich habe darüber in row 10 nur 4 columns in diesem Bereich. Ich muss jetzt aber diese 10 Entries da hinein quetschen.

Bei mir öffnet es manchmal im tk 10 root Fenster. Da wollte ich jetzt den Puffer leeren. Gibt es sowas wie clear() damit nach dem Ausführen nur ein Fenster erscheint.

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

@ichbins: Das klingt im, zusammen mit der Info aus dem gezeigten Quelltext, das wir uns hier schon in Zeile 16 befinden, als wenn Du einfach zu viel mit *einem* Grid lösen willst.

Es öffnen sich nie einfach so 10 Fenster ohne das man Code geschrieben hat der 10 Fenster öffnet. Löse das Problem an der Wurzel und versuche nicht Fenster zu schliessen die gar nicht erst geöffnet werden sollen.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

@ichbins: wenn man interaktiv arbeitet und der Code aus irgendwelchen Gründen abbricht, ist dennoch oft schon das root-Fenster erzeugt. Daher starte Dein Programm immer frisch von der Kommandozeile aus, dann gibt es auch immer nur 1 Fenster.
ichbins
User
Beiträge: 40
Registriert: Samstag 5. September 2020, 07:07

@Blackjack:So ist es auch. Ich habe von oben nach unten gearbeitet und es irgendwie aufgeteilt. Jetzt wurde aus einem Entry 10 Entries. Wie kann man jetzt 10 Entries auf 3 Spalten aufteilen. Kann man das nicht mit einem Frame machen oder dass ich eine Spalte im Hauptprogramm wieder auf Spalten aufteile. Ich kann es ja mit columnspan vergrößern. Wie kann man es aber verkleinern. Irgendwie gefällt mir grid nicht.

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

@ichbins: Dir gefällt grid nicht weil Du „es irgendwie aufgeteilt“ hast. Grid ist für Sachen die sich überwiegend in einem regelmässigen Gitter aufteilen lassen. Nicht einfach für *alles*.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
ichbins
User
Beiträge: 40
Registriert: Samstag 5. September 2020, 07:07

D.h. es gibt keine andere Lösung als die 10 Entry Widgets mit neuen Feldern aufteilen und den Rest der Grafik neu aufteilen. Ich verstehe nicht wieso grid statt place empfohlen wird, Falls man das Fenster erweitern will müsste man alles noch einmal neu aufteilen
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@ichbins: Nein, man muss nicht alles neu aufteilen. Nicht wenn man nicht vorher schon was falsch gemacht hat. Und das hast Du offenbar. Du hast anscheinend einfach *alles* in *ein* Grid gesteckt. Das ist als wenn man alles in eine Funktion schreiben würde. Wenn man Code, Daten, oder auch GUI-Elemente nicht ordentlich strukturiert, hat man irgendwann einen riesigen Klumpen Code, Daten, oder GUI-Elemente wo man Probleme bekommt durchzusteigen oder etwas umzubauen oder zu erweitern.

Nochmal: Ein Grid ist für GUI-Elemente die in einem Gitter angeordnet sind. Also wo die Elemente in einer gewissen (festen) Anzahl von Spalten und Zeilen platziert werden. Zellen zusammenfassen ist eher eine Ausnahme. Wenn also oben im Grid Elemente in drei Spalten aufgeteilt sind und weiter unten plötzlich 10 Spalten gebraucht werden, dann ist das wohl eher nichts für *ein* Grid. Vielleicht auch nicht für zwei (beziehungsweise drei — die zwei müsste man ja auch noch irgendwie anordnen), denn `pack()` gibt es ja auch noch.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten