Pack-Problem

Fragen zu Tkinter.
Antworten
Benutzeravatar
pysq
User
Beiträge: 31
Registriert: Samstag 29. November 2008, 17:48

Hallo.
ich habe eine Buttonklasse geschrieben, und will davon nun mehrere Buttons in einem Frame packen. Etwa so:

Code: Alles auswählen

# -*- coding: cp1252 -*-
import Tkinter as tk


class HLButton(tk.Label):
    def __init__(self, master, command = (None, []), ev = False, relief = 'raised', hvcolor = '#7777ff', \
                 bg = 'SystemButtonFace', **dargs):
        # command should be a method of <master>
        self.hvcolor = hvcolor
        self.bgcolor = bg

        self.command = command
        
        tk.Label.__init__(self)
        self.config(relief = relief, bg = self.bgcolor, **dargs)

        if ev:
            self.bind('<Button-1>', lambda ev: self.command[0](ev))
        else:
            self.bind('<Button-1>', lambda ev: self.command[0](*self.command[1]))
        self.bind('<Enter>', lambda ev: ev.widget.config(bg = self.hvcolor), '+')
        self.bind('<Leave>', lambda ev: ev.widget.config(bg = self.bgcolor), '+')

if __name__ == '__main__':
    root=tk.Tk()
    f = tk.Frame(root)
#    f.pack()
    bt = []
    for i in range(4):
        h = HLButton(f, command = (root.destroy, []), text = 'Schließen')
        h.pack(side = 'left', fill = 'x', expand = True)
        bt.append(h)

    root.mainloop()  
Komischerweise hab ich den Frame noch gar nicht gepackt. Warum erscheint er trotzdem schon in der GUI?

mfg pysq
frohe Weihnachten : )
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo pysq

Die Zeile 14 muss wie folgt lauten:

Code: Alles auswählen

tk.Label.__init__(self, master)
Die Label-Schaltflächen werden bei deinem Beispiel nicht ins Frame abgelegt, sondern in das Hauptfenster.

Der Backslash auf Zeile 6 braucht es nicht.

Gruss wuf :wink:
Take it easy Mates!
Benutzeravatar
pysq
User
Beiträge: 31
Registriert: Samstag 29. November 2008, 17:48

danke = )

EDIT: ... nc
Zuletzt geändert von pysq am Donnerstag 25. Dezember 2008, 12:18, insgesamt 1-mal geändert.
Benutzeravatar
pysq
User
Beiträge: 31
Registriert: Samstag 29. November 2008, 17:48

danke = )
komisch, dass überhaupt kein Fehler kam. Eigentlich ist es ja klar, das ein Label einen master braucht.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo pysq

Tkinter patziert offenbar ein Widget dem nicht explizit einen Master zugeteilt wird automatisch ins Hauptfenster. Ist auch meine erste Feststellung. Danke für deinen interessanten Beitrag.

Gruss wuf :wink:
Take it easy Mates!
Benutzeravatar
pysq
User
Beiträge: 31
Registriert: Samstag 29. November 2008, 17:48

ich habe noch eine andere Frage:

Code: Alles auswählen

from Tkinter import *

root=Tk()
i = PhotoImage(file='grafik.gif')
c=Canvas(root, width=100, height=150, bg = 'red')
c.create_image(50, 75, image = i)
c.pack()

root.mainloop()
grafik.gif ist eine Grafik mit den Maßen 100x150 px.
Beim Packen des Canvas entsteht um die Grafik ein Rand, der nicht erwünscht ist. Die üblichen Optionen padx/ pady usw gibt es bei Canvas jedoch nicht.
Weiterhin wir die Grafik manchmal nicht zentriert dargestellt.
Wie kann ich den Rand beseitigen?

mfg pysq
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo pysq

Sorry ich war die letzten 2 Tage nicht on-line. Der Rand müsste mit der Option 'highlightthickness=0' entfernt werden können. Die Zentrierung des Bildes in der Canvas würde ich einmal mit der Anweisung probieren:

Code: Alles auswählen

c.create_image(0, 0, image=i, anchor='nw')
Hier noch ein Test-Snippet:

Code: Alles auswählen

import Tkinter as tk

root=tk.Tk()
i = tk.PhotoImage(file='my_image.gif')
c = tk.Canvas(root, bg='red', width=i.width(), height=i.height(),
    highlightthickness=0)
c.create_image(0, 0, image=i, anchor='nw')
c.pack()

root.mainloop()
Gruss wuf :wink:
Take it easy Mates!
Benutzeravatar
pysq
User
Beiträge: 31
Registriert: Samstag 29. November 2008, 17:48

das ist auf jeden Fall ein guter Ansatz, danke dafür!
komischerweise funktioniert er jedoch nicht in meiner von tk.Canvas abgeleiteten Klasse:

[code =py]
class Card(tk.Canvas):
"""visualizes a card"""

def __init__(self, master, card):
tk.Canvas.__init__(self, master, bg = card[0], width = image.width(), height = image.height(),
bd = 3, relief = GROOVE, highlightthickness=0)
image = tk.PhotoImage(file="card.gif")
self.create_image(0, 0, image = image, anchor = 'nw')

# [...][/code]

das Canvas wird zwar mit den Maßen angezeigt, aber das Bild nicht..

Gruß pysq
BlackJack

Du must auf der "Python-Seite" eine Referenz auf das Bild behalten, sonst wird das Python-Objekt von der Speicherbreinigung abgeräumt und Tk hat nichts mehr zum Anzeigen.
Benutzeravatar
pysq
User
Beiträge: 31
Registriert: Samstag 29. November 2008, 17:48

okay, das funktioniert. thx : )
Antworten