tkinder im Modul funzt nicht

Fragen zu Tkinter.
Antworten
GiJay
User
Beiträge: 36
Registriert: Freitag 5. März 2021, 14:40
Wohnort: Ratingen
Kontaktdaten:

Einen schönen Gruß an die Gemeinde,

habe mich neu angemeldet und bin auch ein "Beginner". "Wühle" mich durchs www und habe irgendwo die Empfehlung gelesen, dass es durchaus Sinn macht sein Script in Module zu verfassen, da dann der Überblick leichter fällt. Gesagt, aber falsch getan.

Im Mainscript importiere ich tkinder, definere das Mainfenster und richte 2 Frames ein.
Vom Modul aus wollte ich nun die Frames mit Button und Label füllen. Leider erkennt er die Begriffe "Label" und "Button" aus tkinder nun nicht mehr? Alles in einem Script funktioniert wie gewünscht.
Trenne wollte ich das Script, da die Frames im Mainscript verschiedene Inhalte erhalten sollen.

Ein Tipp von Euch wäre schön !

Code: Alles auswählen

from tkinter import *
from core import m_BSiteOne

#Farben definieren
#FFFFFF=Weiß A1A1A1=Grau 000000=schwarz ...
f_bgMainWindow  = '#FFFFFF' #weiß
f_bgFrameWork   = '#A1A1A1' #grau
f_bgFrameButton = '#000000' #weiß

#Globale Variable
v_AktiveSite = 1 # Aktive Seite bei Programmstart

# Ereignisverarbeitung
def Button_Click_Fanfare():
	exit()
def Button_Click_Led():
	exit()
def Button_Click_Gyro():
	exit()
def Button_Click_WStrg():
	exit()

# Erzeugen des HauptFensters
mainWindow = Tk()
mainWindow.config(bg=f_bgMainWindow)
mainWindow.geometry('640x480')
mainWindow.overrideredirect(TRUE) #ohne Zeile und Menü

### Erzeugen der einzelnen Frames (Container)

# frameWork zur Anzeige der einzelnen TeilProgramme
frameWork = Frame(mainWindow, bg=f_bgFrameWork)
frameWork.place(x=10, y=5, width=625, height=300)

# frameButton zur Anzeige des Button-Containers
frameButton = Frame(mainWindow, bg=f_bgFrameButton)
frameButton.place(x=10, y=320, width=630, height=150)

### Schleife
if v_AktiveSite == 1:
		m_BSiteOne.frameButtonSiteOne() 
	
### Aktivierung des Fensters
mainWindow.mainloop()

Code: Alles auswählen

#Modul m_ButtonSiteOne
def frameButtonSiteOne(): 
		
	# frameWork - Inhalt
	labelWork = mainWindow.Label(master=frameWork, text='Start', font=("Arial", 18))
	#labelWork.lift()

	# frameButton - Inhalt
	buttonFanfare = Button(frameButton, text='Fanfare', command = Button_Click_Fanfare)
	
	#
	buttonLed = Button(frameButton, text='Led', command = Button_Click_Led)
	
	#
	b_imageGyro = PhotoImage(file="../image/ButtonGyro.gif")
	buttonGyro = Button(frameButton, relief=FLAT, bg=f_bgFrameButton, highlightthickness=0, pady=0, padx=0, image=b_imageGyro, command = Button_Click_Gyro)
	
	#
	b_imageStrg = PhotoImage(file="image/ButtonStrg.gif")
	buttonWStrg = Button(frameButton, relief=FLAT, bg=f_bgFrameButton, highlightthickness=0, pady=0, padx=0, image=b_imageStrg, command = Button_Click_WStrg)

	#Button plazieren
	buttonFanfare.place(x=27, y=5, width=140, height=140)
	buttonLed.place(x=178, y=5, width=140, height=140)
	buttonGyro.place(x=329, y=5, width=140, height=140) 
	buttonWStrg.place(x=481, y=5, width=140, height=140)

#Ende
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

So ist das in Python. Der Import in einem Modul/Skript ist in einem anderen nicht sichtbar. Du musst das da eben auch importieren. Und man importiert nicht mit "from modul import *", weil das den Namensraum unkontrolliert zumuellt. Sondern zB bei tkinter mit

import tkinter as tk

womit sich dann Dinge wie Buttons und co mit

tk.Button(root, ...)

erstellen lassen.
Benutzeravatar
__blackjack__
User
Beiträge: 12984
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@GiJay: Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).

Und gewöhne Dir so komische Präfixe und kryptische Abkürzungen in Namen gar nicht erst an.

Funktionen und Methoden werden üblicherweise nach der Tätigkeit benannt die sie durchführen. Damit man sie von eher passiven Werten unterscheiden kann.

Man verwendet keine globalen Variablen.

Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

Kommentare sollen dem Leser einen Mehrwert über den Code geben. Faustregel: Kommentare beschreiben nicht *was* der Code macht, denn das steht da bereits als Code, sondern warum er das macht. Sofern das nicht offensichtlich ist. Offensichtlich ist in aller Regel auch was in der Dokumentation von Python und den verwendeten Bibliotheken steht.

Verwende kein `place()`. Das ist ein Albraum was Wartung und Weiterentwicklung angeht und es funktioniert auch nicht wirklich, weil die Grössen und Positionen auf anderen Systemen mit anderen Einstellungen, Monitorgrössen, Schriftarten/-grössen falsch sein können, bis hin zu unbenutzbaren GUIs.

Die beiden Module sind keine zwei Module. Die brauchen sich gegenseitig, also macht es wenig Sinn und nur unnötige Probleme die in zwei Module aufzuteilen. Modulabhängigkeiten bilden eine Hierarchie. Wenn Modul A Modul B braucht, dann darf das nicht umgekehrt auch gelten.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
GiJay
User
Beiträge: 36
Registriert: Freitag 5. März 2021, 14:40
Wohnort: Ratingen
Kontaktdaten:

@_deets_
Oh, das ist aber eine unangenehme Info :-) "Ein Modul / Script ist in einem anderen nicht sichtbar." Wenn ich also ein Script mit Ausgabe von 3 verschiedenen Bildschirminhalten haben möchte, schreibe ich entweder alles in ein Script oder schreibe für jeden Bildschirm ein Script .... Da muss jetzt erst einmal drüber nachdeneken, was da wohl sinnvoller ist. Vielen Dank für diesen gravierenden Einblick !!!

@_blackjack_
Auch Dir ein Danke, dass Du meinen Thread gelesen hast.
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das eine einzelne Zeile "import tkinter as tk" jetzt "unangenehm" ist, sehe ich nicht. Auch wenn die dreimal geschrieben werden muss in Summe. Was ich unangenehm faende waere, wenn ich IRGENDWO in meinem Programm einen import hinzufuege, und es dadurch ploetzlich zu einer Namenskollision an einer beliebigen anderen Stelle im Code kommt. Ohne das ich eine Chance habe, das nachzuvollziehen.
Benutzeravatar
__blackjack__
User
Beiträge: 12984
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@GiJay: Nein, Du musst nicht für jeden Bildschirm ein komplettes Programm schreiben. Du kannst da auch Module für verwenden. Du musst das nur vernünftig aufteilen, so dass sich keine Module gegenseitig verwenden und nicht einfach auf magische Weise alles überall global verfügbar sein muss, sondern sauber übergeben wird. Funktionen (und Methoden) bekommen alles was sie ausser Konstanten benötigen als Argument(e) übergeben.

Das wird vielleicht auch einfacher wenn Du das mit der Hauptfunktion und keinen globalen Variablen berücksichtigt, denn das führt bei jeder nicht-trivialen GUI dazu, dass man sinnvollerweise objektorientierte Programmierung verwendet.

Wie soll das mit den „Bildschirmen“ denn am Ende funktionieren? Erfindest Du da am Ende ein `tkinter.ttk.Notebook` neu, statt *das* zu nehmen?

Weitere Anmerkungen: Eingerückt wird per Konvention mit vier Leerzeichen pro Ebene, nicht mit Tabulatorzeichen.

`exit()` muss man aus dem `sys`-Modul importieren. Dass das einfach so ohne expliziten Import geht ist undokumentiert, da kann man sich also nicht drauf verlassen. *Aber*: Der Aufruf sollte sowieso in Rückruffunktionen oder irgendwo ausserhalb der oberen Aufrufebenen stehen. Wenn man eine Tkinter-GUI beenden will, dann beendet man die GUI-Hauptschleife mit der `quit()`-Methode die es auf jedem Widget-Objekt gibt. Dann wird auch Code nach dem `mainloop()`-Aufruf noch ausgeführt wo man noch weitere Aufräumarbeiten unterbringen kann.

`exit()` sollte man nur verwenden wenn man mindestens potentiell auch etwas anderes als 0 als Rückgabecode an den Aufrufer des Programms übermitteln will. Weil *das* der eigentliche Zweck dieser Funktion ist. Nicht ein kurzer ”Notausstieg” zu sein, weil man keinen ordentlichen Programmablauf bis zu einem normalen Ende hinbekommen hat.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten