Seite 1 von 2
button placement.
Verfasst: Mittwoch 24. Januar 2018, 22:07
von jan.b
Hallo, wie kann ich diesen button umposittionieren? und was tut mainloop(hat damit nichts zu tun. würde ich trotzdem gerne wissen.)
danke schon mal.
from tkinter import*
tk = Tk()
canvas = Canvas(tk, width=400, height=400)
canvas.pack()
def hi():
print("hi")
btn = Button(tk, width=20, height=30, text="hallo", fg='red', bg='black', command=hi)
btn.pack()
Re: button placement.
Verfasst: Mittwoch 24. Januar 2018, 22:20
von __deets__
Lange nicht mehr da gewesen - immer noch nicht gelernt, Code in die Codebox zu stecken....
Was deine mainloop Frage angeht: diese Thema wird ganz akut hier im Tkinter Forum diskutiert. In das dein Posting übrigens auch gehört.
Und ohne zu wissen wie das Ergebnis aussehen soll, kann man deine Hauptfrage auch nicht beantworten.
Re: button placement.
Verfasst: Mittwoch 24. Januar 2018, 22:25
von jan.b
ok. das Ergebnis soll sein, dass ich weiß, wie man buttons platziert. also wäre eine dementsprechende antwort nett.

Re: button placement.
Verfasst: Mittwoch 24. Januar 2018, 22:42
von __deets__
Du hast also wirklich kein einziges Beispiel im großen weiten Internet gefunden, in dem Buttons platziert werden? Und auch nicht hier im Forum, in dem zB Wuf permanent so etwas postet? Da bleibt nur der Schluss, das du weder Hände noch Augen hast, womit es ja dann auch egal ist, ob du einen Button platziert bekommst, ist ja eh nicht sicht- und benutzbar für dich

Re: button placement.
Verfasst: Mittwoch 24. Januar 2018, 22:43
von jan.b
harter diss. leider nicht hilfreich aber trotzdem hart.
Re: button placement.
Verfasst: Mittwoch 24. Januar 2018, 23:09
von __deets__
Doch doch, hilfreich war der schon. Du bist halt ein bisschen sehr ignorant den dir gegebene Tipps gegenüber. Selbst in dem “harten Diss” habe ich dir erzählt, wie du an Beispiele kommst. Und Erklärungen.
Wenn du jemanden suchst, der dir auf hingerotzte zwei Sätze einen interaktiven Roman mit Tonspur & Glitzerstaub liefert, wirst du jemanden dafür bezahlen müssen. Wenn du HIER Hilfe willst, wirst du deutlich mehr liefern müssen. Aber das haben wir dir ja nun schon seit Anbeginn deiner Karriere hier dargelegt, oder?
Re: button placement.
Verfasst: Donnerstag 25. Januar 2018, 07:32
von noisefloor
Hallo,
Tkinter kennt drei verschiedene Layout Manager, damit kannst du Element platzieren. Wenn du jetzt fragen möchtest: "Wie?" -> RTMF. Dazu gibt es etliche Threads hier im Forum und tausende Seiten im Internet.
`btn = Button(tk, width=20, height=30, text="hallo", fg='red', bg='black', command=hi)` ist IMHO relativ sinnfrei - warum soll sich ein Button bei ein Klick darauf selber aufrufen?
Der mainloop macht das, was der Name sagt: es ist die Hauptschleife von Tkinter, die alle Interaktionen mit der GUI kontrolliert bzw. darauf reagiert.
Gruß, noisefloor
Re: button placement.
Verfasst: Donnerstag 25. Januar 2018, 21:55
von jan.b
der button ruft sich ja über btn.pack auf. und ich glaube ohne geht's nicht.
Re: button placement.
Verfasst: Donnerstag 25. Januar 2018, 21:59
von jan.b
ich habe ehrlich gesagt nicht genug zeit für den ganzen quatsch. manchmal brauche ich schnelle präzise antworten auf spezifische fragen. @noisenfloor hat's ja auch irgendwie hinbekommen einen antwort satz zu schreiben, der ein wenig hilfreich war. es ist nicht die konventionelle art etwas zu lernen, aber wenn du eine frage siehst, auf die du in ein oder zwei sätzen antorten kannst, wäre es einfach nur nett dies auch zu tun.
Re: button placement.
Verfasst: Freitag 26. Januar 2018, 07:19
von noisefloor
Hallo,
@jan.b: Wenn du präzisere Antworten brauchst, dann stell' doch aml präzise Fragen. Was heißt "umpositionieren"? Du hast eine 400x400px großes Fenster mit einem Button. Umpositionieren kann alles mögliche sein - links oben, rechts unten, horizontal mittig 25% außerhab der vertikalen Mitte usw.
`pack()`kennt zusätzliche Argumente zu Positionierng -> RTMF
Außerdem mangelt es deiner Art der Kommunikation hier, also wie du antwortest, manchmal doch ein sozialer Verträglichkeit. Sprich die Motivation der hier regelmäßig helfenden, zu antworten, ist dann eher gering.
Und außerdem liegt bei dir auch immer, bezogen auf die Fragen und Antworten die Vermutung nah, dass deine Motivation, selber etwas herauszufinden und zu erarbeiten, eher gering ist. Hier im Forum gibt's Hilfe zur Selbsthilfe. Wenn Selbsthilfe nicht so dein Ding ist, dann ist das auch ein schlechter Ausgangspunkt für python-forum.de.
Gruß, noisefloor
Re: button placement.
Verfasst: Freitag 26. Januar 2018, 09:23
von __deets__
Keine deiner Fragen hier im Thread war spezifisch. Und du bist ein Schüler, du weißt noch nicht mal , was es heißt, keine Zeit zu haben. Mal abgesehen davon, das es kein Quatsch ist, was wir hier verlangen. Sondern notwendig. Was du überhaupt nicht einschätzen kannst, mangels Grundlagen.
Du hast einfach keinen Bock drauf auch nur ein Iota Anstrengung zu unternehmen, sondern willst ohne eigenen Aufwand abgreifen. Wird nix werden.
Re: button placement.
Verfasst: Freitag 26. Januar 2018, 13:32
von wuf
__deets__ hat geschrieben:Wuf permanent so etwas postet?
Hier ist der 'wuf' schon wieder:
Hi Jan.b
Habe hier eine kleine Demo für die Platzierung des Buttons mit dem Pack-Layouter geschrieben:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Tkinter for Python 3.xx
import tkinter as tk
APP_TITLE = "Button placing with pack layouter"
APP_XPOS = 100
APP_YPOS = 100
APP_WIDTH = 600
APP_HEIGHT = 200
SIDES = ['top', 'right', 'bottom', 'left']
ANCHORS = ['center', 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw']
FONT = ('Helevetica', 14, 'bold')
class Application(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.title(APP_TITLE)
def build(self):
self.protocol("WM_DELETE_WINDOW", self.close_app)
self.geometry("+{}+{}".format(APP_XPOS, APP_YPOS))
self.geometry("{}x{}".format(APP_WIDTH, APP_HEIGHT))
self.option_add("*Button.highlightThickness", 0)
frame = tk.Frame(self, bg='#FFFF00')
frame.pack(fill='both', expand=True)
self.pos_var = tk.StringVar()
self.button = tk.Button(frame, textvariable=self.pos_var, width=18,
height=2, font=FONT)
self.button.pack(padx=10, pady=10)
self.place_the_button()
def place_the_button(self, pos_index=0, pos_mode='side'):
if pos_mode == 'side':
side = SIDES[pos_index]
self.pack_with_side(side)
pos_index += 1
if pos_index >= len(SIDES):
pos_index = 0
pos_mode = 'anchor'
elif pos_mode == 'anchor':
anchor = ANCHORS[pos_index]
self.pack_with_anchor(anchor)
pos_index += 1
if pos_index >= len(ANCHORS):
pos_index = 0
pos_mode = 'side'
self.after(2000,self.place_the_button, pos_index, pos_mode)
def pack_with_side(self, side):
# Wichtige voreingestellte Optionen für die Anwendung von 'side' sind:
# 'anchor' = 'center'
# 'expand' = False
print('Side:', self.button.pack_info())
self.button.config(bg='#90EE90')
self.pos_var.set("Position with side:\n'{}'".format(side))
self.button.pack_configure(side=side, anchor='center', expand=False)
def pack_with_anchor(self, anchor):
# Wichtige voreingestellte Optionen für die Anwendung von 'anchor' sind:
# 'expand' = True
print('Anchor:', self.button.pack_info())
self.button.config(bg='#1AB7EA')
self.pos_var.set("Position with anchor:\n'{}'".format(anchor))
self.button.pack_configure(anchor=anchor, expand=True)
def close_app(self):
# Here do something before apps shutdown
print("Good Bye!")
self.destroy()
def main():
app = Application()
app.build()
app.mainloop()
if __name__ == '__main__':
main()
Gruss wuf

Re: button placement.
Verfasst: Freitag 26. Januar 2018, 14:44
von __deets__
Wenn es nur eine Moeglichkeit gegben haette, sich solcher Art Code hier aus dem Forum rauszusuchen...
https://www.google.com/search?q=site%3A ... e&ie=UTF-8
@wuf: wenn die App-Klasse eh nur sinnvoll ist, wenn "build" aufgerufen wird, ist es angezeigt, diesen Aufruf gleich in __init__ zu taetigen.
Fuer mainloop gilt das natuerlich nicht. Das sollte getrennt bleiben, damit man zwischen App instantiieren und Eintritt in die Ereignisbearbeitung noch Luft hat.
Re: button placement.
Verfasst: Freitag 26. Januar 2018, 15:23
von wuf
@__deets__: Danke für deinen Tipp. Habe mein Skript angepasst:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Tkinter for Python 3.xx
import tkinter as tk
APP_TITLE = "Button placing with pack layouter"
APP_XPOS = 100
APP_YPOS = 100
APP_WIDTH = 600
APP_HEIGHT = 200
SIDES = ['top', 'right', 'bottom', 'left']
ANCHORS = ['center', 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw']
FONT = ('Helevetica', 14, 'bold')
class Application(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.title(APP_TITLE)
self.build()
def build(self):
self.protocol("WM_DELETE_WINDOW", self.close_app)
self.geometry("+{}+{}".format(APP_XPOS, APP_YPOS))
self.geometry("{}x{}".format(APP_WIDTH, APP_HEIGHT))
self.option_add("*Button.highlightThickness", 0)
frame = tk.Frame(self, bg='#FFFF00')
frame.pack(fill='both', expand=True)
self.pos_var = tk.StringVar()
self.button = tk.Button(frame, textvariable=self.pos_var, width=18,
height=2, font=FONT)
self.button.pack(padx=10, pady=10)
self.place_the_button()
def place_the_button(self, pos_index=0, pos_mode='side'):
if pos_mode == 'side':
side = SIDES[pos_index]
self.pack_with_side(side)
pos_index += 1
if pos_index >= len(SIDES):
pos_index = 0
pos_mode = 'anchor'
elif pos_mode == 'anchor':
anchor = ANCHORS[pos_index]
self.pack_with_anchor(anchor)
pos_index += 1
if pos_index >= len(ANCHORS):
pos_index = 0
pos_mode = 'side'
self.after(2000,self.place_the_button, pos_index, pos_mode)
def pack_with_side(self, side):
# Wichtige voreingestellte Optionen für die Anwendung von 'side' sind:
# 'anchor' = 'center'
# 'expand' = False
print('Side:', self.button.pack_info())
self.button.config(bg='#90EE90')
self.pos_var.set("Position with side:\n'{}'".format(side))
self.button.pack_configure(side=side, anchor='center', expand=False)
def pack_with_anchor(self, anchor):
# Wichtige voreingestellte Optionen für die Anwendung von 'anchor' sind:
# 'expand' = True
print('Anchor:', self.button.pack_info())
self.button.config(bg='#1AB7EA')
self.pos_var.set("Position with anchor:\n'{}'".format(anchor))
self.button.pack_configure(anchor=anchor, expand=True)
def close_app(self):
# Here do something before apps shutdown
print("Good Bye!")
self.destroy()
Application().mainloop()
Gruss wuf

Re: button placement.
Verfasst: Freitag 26. Januar 2018, 16:03
von kbr
@Wuf: die Reduktion auf
ist auch nicht ideal, denn so verwirfst Du das Applikationsobjekt unmittelbar, sobald die Mainloop beendet wird. Dein vorheriger Ansatz, allerdings ohne den Aufruf von 'build', da dieses nach dem Hinweis von __deets__ nun in der Initialisierung mit integriert ist, war da sauberer. Kompakten Code zu schreiben ist gut, zu kompakt hingegen bringt keinen Vorteil.
Re: button placement.
Verfasst: Freitag 26. Januar 2018, 16:16
von wuf
Hi kbr
Danke auch für deinen Tipp. Habe mein Skript wieder korrigiert:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Tkinter for Python 3.xx
import tkinter as tk
APP_TITLE = "Button placing with pack layouter"
APP_XPOS = 100
APP_YPOS = 100
APP_WIDTH = 600
APP_HEIGHT = 200
SIDES = ['top', 'right', 'bottom', 'left']
ANCHORS = ['center', 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw']
FONT = ('Helevetica', 14, 'bold')
class Application(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.title(APP_TITLE)
self.build()
def build(self):
self.protocol("WM_DELETE_WINDOW", self.close_app)
self.geometry("+{}+{}".format(APP_XPOS, APP_YPOS))
self.geometry("{}x{}".format(APP_WIDTH, APP_HEIGHT))
self.option_add("*Button.highlightThickness", 0)
frame = tk.Frame(self, bg='#FFFF00')
frame.pack(fill='both', expand=True)
self.pos_var = tk.StringVar()
self.button = tk.Button(frame, textvariable=self.pos_var, width=18,
height=2, font=FONT)
self.button.pack(padx=10, pady=10)
self.place_the_button()
def place_the_button(self, pos_index=0, pos_mode='side'):
if pos_mode == 'side':
side = SIDES[pos_index]
self.pack_with_side(side)
pos_index += 1
if pos_index >= len(SIDES):
pos_index = 0
pos_mode = 'anchor'
elif pos_mode == 'anchor':
anchor = ANCHORS[pos_index]
self.pack_with_anchor(anchor)
pos_index += 1
if pos_index >= len(ANCHORS):
pos_index = 0
pos_mode = 'side'
self.after(2000,self.place_the_button, pos_index, pos_mode)
def pack_with_side(self, side):
# Wichtige voreingestellte Optionen für die Anwendung von 'side' sind:
# 'anchor' = 'center'
# 'expand' = False
print('Side:', self.button.pack_info())
self.button.config(bg='#90EE90')
self.pos_var.set("Position with side:\n'{}'".format(side))
self.button.pack_configure(side=side, anchor='center', expand=False)
def pack_with_anchor(self, anchor):
# Wichtige voreingestellte Optionen für die Anwendung von 'anchor' sind:
# 'expand' = True
print('Anchor:', self.button.pack_info())
self.button.config(bg='#1AB7EA')
self.pos_var.set("Position with anchor:\n'{}'".format(anchor))
self.button.pack_configure(anchor=anchor, expand=True)
def close_app(self):
# Here do something before apps shutdown
print("Good Bye!")
self.destroy()
def main():
app = Application()
app.mainloop()
if __name__ == '__main__':
main()
Noch ein Frage im Zusammenhang mit dem Aufruf von 'build' in der Klasse Application. Ist es problematisch wenn sich in dieser Methode weitere 10'000 Zeilen Kode befinden?
Gruss wuf

Re: button placement.
Verfasst: Freitag 26. Januar 2018, 16:32
von noisefloor
Hallo,
Ist es problematisch wenn sich in dieser Methode weitere 10'000 Zeilen Kode befinden?
Laufen tut das - nur ist eine Funktion mit 10.000 Zeilen Code nicht wartbar, darin findet du ja nichts mehr wieder... Das sollte man dann in mehr Funktionen runter brechen. Das ist aber nicht tkinter-spezifisch, dass gilt für jeglichen Code.
Gruß, noisefloor
Re: button placement.
Verfasst: Freitag 26. Januar 2018, 16:37
von kbr
@Wuf: Bei der Instanziierung eines Objektes sollte nichts weiter geschehen, als dieses Objekt in einen 'gebrauchsfähigen' Zustand zu versetzen. Wenn dafür 10000 Zeilen Code erforderlich sind, würde ich die Architektur hinterfragen. In der Praxis mag sowas zustande kommen, wenn ein Objekt sehr komplex ist und eine Vielzahl anderer Objekte als Attribute enthält (für die das ggf. auch wieder gilt). Für Python sind 10000 Zeilen Code bereits extrem viel.
Als Nachtrag noch: bei
hast Du zudem die Möglichkeit, zwischen der Instanziierung und dem Aufruf der Mainloop, noch was einzufügen. So auch 'build', wie Du es ursprünglich getan hattest, aber dieses ist funktional der Initialisierung zuzuordnen und daher dort besser aufgehoben.
Re: button placement.
Verfasst: Freitag 26. Januar 2018, 17:21
von wuf
@noisefloor & kbr: Danke für eure Antworten.
OK ich habe natürlich ein wenig übertrieben mit den 10'000 Zeilen Code. Es könnten ja viel weniger Zeilen sein aber dafür ein Zeit konsumierender Algorithmus der in der Methode
'build' abgearbeitet wird. Meine Frage ist wäre es ein Unterschied, wenn dieser Zeit konsumierend Block in der __init__ Methode ausgeführt wird oder in der Klasse 'Application' aus der _init__ Methode aufgerufenen Methode 'build' abgearbeitet würde. Wenn diese zwei Varianten keinen Unterschied ausmachen wäre es dann doch besser die folgende Variante anzuwenden?:
Code: Alles auswählen
def main():
app = Application()
app.build()
app.mainloop()
if __name__ == '__main__':
main()
So würde doch die __init__ Methode der Klasse 'Application' sofort vor dem zeitintensiven Block in der 'build'Methode ausgeführt werden?
N.B: Hoffe mich richtig ausgedrückt zu haben.
Gruss wuf

Re: button placement.
Verfasst: Freitag 26. Januar 2018, 17:30
von __deets__
Die Frage ist, was das build macht. Wenn du es weg lassen kannst, und das ganze ist immer noch sinnvoll zu nutzen - dann vielleicht. Aber wenn - wie bei dir - sowieso nach Konstruktion *IMMER* build aufrufen musst, dann ist alles was du geschafft hast eine Fehlerquelle einzubauen - wehe jemand vergisst, build aufzurufen. Die Laufzeit wird aber dadurch nicht besser, wieso sollte sie? Die Menge an Anweisungen ist gleich, und damit auch die Laufzeit.
Generell ist es eine selten sinnvolle Idee, Objekte zu bauen, fuer die man erst magische Zaubesprueche in Form von diversen Methodenaufrufen in genau der richtigen Reihenfolge taetigen muss, bevor sie was tun.