Seite 1 von 1
ttk buttons/widget states
Verfasst: Donnerstag 12. August 2021, 16:48
von blackdiamont
Moinsen,
ich hoffe ihr könnt mir Helfen und bin auch im richtigen Forum

Bisher progge ich in PHP und C (Arduino), daher bin ich noch nicht so bewandert mit Python.
Ich habe mir eine App
geforked welche auf picamera und ttk basiert.
Hier bin ich dabei die offenen ToDo's etc zu verwirklichen, was auch Hindernisse mit sich bringt wo ich erst einmal Doku's etc durchforsten muss um zu verstehen wie es funktioniert usw.
Aktuell hänge ich am "simplen" Button "disablen", was laut Doku mit state="disabled" funktioniert (Testcode tut).
Die Buttons.py bereitet mir etwas Kopfschmerzen ... es geht um den MultiTouchButton.
Code: Alles auswählen
LangLabel(f10,text='Exposure Mode:',
language=self.language).grid(row=4,column=0,sticky='E',pady=(15,0))
self.exposureMode = MultiTouchButton(f10,text=['off','auto','night','nightpreview','backlight','spotlight','sports','snow','beach','verylong','fixedfps','antishake','fireworks'],
value=Globals.exposureMode,language=self.language,
background=Globals.defaultBackgroundColor,
callback=self.ExposureModeChanged,width=200)
self.exposureMode.grid(row=4,column=1,padx=(15,0),pady=(15,0))
self.ExposureModeChanged(Globals.exposureMode)
Der Button funktioniert an sich, allerdings soll dieser deaktiviert werden sobald ISO nicht mehr auf auto steht.
Mein simpler Gedanke bzw eher versuch war ein state="disabled" hinzuzufügen, was ignoriert wird ...
Bin mir auch nicht sicher ob dieser Code nur einmal ausgeführt wird beim Start oder dauerhaft, was nMm der Fall sein sollte.
Habt ihr eine Idee?
Grüssle
BLACK
Re: ttk buttons/widget states
Verfasst: Donnerstag 12. August 2021, 20:08
von Sirius3
Da ist so einiges schlecht an dem Code, den Du Dir da ausgesucht hast. Variablen und Methoden schreibt man komplett klein, man rückt mit 4 Leerzeichen pro Ebene ein und nicht mit Tabs. Man bricht eine Zeile immer nach einem : um, man benutzt keine nackten Excepts. Man verwendet keine *-Importe.
Deshalb sollte MultiTouchButton eigentlich ungefähr so aussehen:
Code: Alles auswählen
class MultiTouchButton(ttk.Frame):
def __init__(self, parent, *args, **kargs):
ttk.Frame.__init__(self, parent)
self.config(style='F.TFrame')
self._parent = parent
self._callback = kargs.get('callback')
self.lang = kargs.get('language')
self._text = kargs['text']
if not isinstance(self._text, list) or not isinstance(self._text[0], str):
raise ValueError("'text' must be a list of strings")
self._width = int(kargs.get('width', 50))
self._height = int(kargs.get('height', Globals.defaultButtonHeight))
self.value = kargs['value']
self._canvas = Canvas(self,
width=self._width,
height=self._height,
background=Globals.buttonbackcolor)
self._canvas.grid(row=0, column=0)
self._canvas.bind('<Button-1>', self.pressed)
self._canvas.bind('<ButtonRelease-1>', self.released)
self._text_area = self._canvas.create_text(
(int(self._width / 2), int(self._height / 2)),
font=Globals.defaultFont,
fill=Globals.buttontextcolor,
text='')
self.draw_text()
def pressed(self, event):
self._canvas.config(background=Globals.buttonpressedcolor)
self._canvas.itemconfig(self._text_area, fill=Globals.buttonpressedtextcolor)
def released(self, event):
self._value += 1
if self._value >= len(self._text):
self._value = 0
self._canvas.config(background=Globals.buttonbackcolor)
self.draw_text()
if self._callback:
self._callback(self._value)
@property
def value(self):
return self._value
@value.setter
def value(self, val):
self._value = min(len(self._text) - 1, max(0, int(val)))
self.draw_text()
def draw_text(self):
txt = self._text[self._value]
if self.lang:
txt = self.lang.get_text(txt)
self._canvas.itemconfig(
self._text_area,
fill=Globals.buttontextcolor,
text=txt)
def update_language(self):
self.draw_text()
Und das ist kein Button sondern ein Canvas und daher funktioniert auch state nicht, wenn man es nicht selbst programmiert.
Warum das kein Button ist, ist das Geheimnis des ursprünglichen Programmierers.
Re: ttk buttons/widget states
Verfasst: Freitag 13. August 2021, 07:41
von blackdiamont
Danke für dein schnelle Antwort.
Also erstes ToDo wäre quasi den Code zu überarbeiten ... uff :/
Die Buttons kann ich ja nach deinem Beispiel einmal überarbeiten und schaue mir die Doku zu den Canvas einmal an.
Muss sagen das mit dem Einrücken via Tabs finde ich angenehmer als mit Leerzeichen, aber ich denke mal das ist so ne "Glaubenssache"

Re: ttk buttons/widget states
Verfasst: Freitag 13. August 2021, 12:43
von __blackjack__
@blackdiamont: Eine sehr starke Glaubenssache, beziehungsweise teilweise halt auch nicht, denn Einrückung ist Teil der Syntax, also glaubt der Compiler auch daran. Und wenn das lesbar und unmissverständlich für Menschen sein soll, dann darf man Tabs und Leerzeichen nicht mischen. *Alle* nehmen vier Leerzeichen und keine Tabs. Das ist ähnlich wie die Frage auf welcher Seite der Strasse man fährt. Eigentlich ist es ja egal ob man das wie bei uns oder wie in England macht. Solange das alle gleich machen. Mit Tabs bist Du bei Python der Geisterfahrer. Und wenn es einen Unfall gibt, ist das Deine Schuld.
Was ist an Tabs angenehmer? Jeder brauchbare Editor kann so eingestellt werden, dass bei der Tab-Taste vier Leerzeichen eingefügt werden, beziehungsweise so viele Leerzeichen wie nötig sind um an die entsprechende Stelle zu kommen. Und das selbe wenn man die Rücktaste drückt, dass dann entsprechend viele Leerzeichen entfernt werden. Also genau wie bei Tabs.
Welche Frage sich bei Leerzeichen *nicht* mehr stellt, ist wo denn eigentlich die Tabstops liegen. Alle 8 Zeichen? Alle 4 Zeichen? Was anderes? Oder gar nicht regelmässig? Und bekommt man das überall gleich hin? Wo stellst Du das im Browser ein? Wo im E-Mail-Client? Wo im Terminal? Eine halbwegs ”sichere” Einstellung wäre der Tabstop alle 8 Zeichen. Das ist aber für *eine* Einrückungsebene ziemlich (zu) gross. Aber Leerzeichen und Tabs mischen führt sehr leicht zu Problemen weil man leicht Code schreiben kann der was anderes bedeutet als der visuelle Eindruck vermittelt.
Konvention ist vier Leerzeichen pro Ebene, und diese Konventionen sind in aller Regel ziemlich starke Überzeugungen. Der wohl beliebteste Autoformatter für Python-Quelltext hat genau zwei mögliche Stellschrauben: Maximale Zeilenlänge, weil der Style Guide da zwischen 79 und 120 Zeichen pro Zeile vorsieht, und ob alle Zeichenkettenliterale von ' auf " als Begrenzer umgestellt werden sollen oder nicht. Alles andere ist nicht mehr die Entscheidung des Autors vom Quelltext der formatiert wird. Da wird nach
Style Guide for Python Code formatiert, und wo dort Freiheiten gegeben sind, ist ein wichtiges Kriterium von black (so heisst der Formatter) das möglichst sinnvolle Diffs bei künftigen Änderungen entstehen.
Re: ttk buttons/widget states
Verfasst: Freitag 13. August 2021, 14:22
von blackdiamont
Mischen ist klar, auf irgendwas sollte man sich schon einigen. Das sehe ich auch bei PHP so, entweder Prozedural oder OOP (hier bin ich auch der Prozedurale Fan). Einrücken joa mit Tabs gewohnt eigentlich, gerade im Terminal sehr angenehm daher bin ich der Tab Fan
Muss auch zugeben, bis auf die Arduino IDE verwende ich für alles andere keine IDE sondern gedit, nano oder wenn ich gerade kein Linux System habe den Notepad++.
Vielleicht gibt es ja eine IDE die ich für alles nutzen kann, auch unterwegs

Re: ttk buttons/widget states
Verfasst: Freitag 13. August 2021, 14:47
von Sirius3
@blackdiamont: __blackjack__ hat nirgends was von IDE geschrieben. gedit, nano, Notepad++, alle kann man so einstellen, dass die Einrückung mit 4 Leerzeichen beim Drücken der Tab-Taste erfolgt, wenn es nicht gar schon die Standardeinstellung für Python-Quelltext ist.
Und wo rückst Du im Terminal mit Tabs ein?
Re: ttk buttons/widget states
Verfasst: Freitag 13. August 2021, 16:01
von blackdiamont
Das mit IDE war ein Gedanke von mir.
Mit Terminal meine ich nano, vim etc
Re: ttk buttons/widget states
Verfasst: Freitag 13. August 2021, 16:23
von Sirius3
Auch vim rückt beim Drücken von Tab mit Leerzeichen ein.
Bei Python-Quelltext ist das bei mir sogar voreingestellt.
Re: ttk buttons/widget states
Verfasst: Freitag 13. August 2021, 16:29
von blackdiamont
Habs bei gedit eingestellt und auch leerzeichen statt Tab.
Danke schon mal soweit
Sirius3 hat geschrieben: Donnerstag 12. August 2021, 20:08
Man verwendet keine *-Importe.
Hast du mir ein Beispiel wie es korrekt sein sollte? Von der
Doku selbst wird das so vorgegeben
Wie ist das mit dem "Mainloop" diesen ruft er mit
auf, aber sehe nicht von welcher Zeile er Anfängt und Endet ...
Kenne das bisher nur mit while, for oder until Schleifen.
Re: ttk buttons/widget states
Verfasst: Freitag 13. August 2021, 18:24
von Sirius3
Ja, auch Dokumentationen sind nicht perfekt. Und die Dokumentation beschreibt auch gleich die Probleme, die man damit hat, nämlich dass das nicht 100% ersetzbar ist und man zum Schluß nicht weiß, welches Label denn benutzt wird, bzw. es davon abhängt, in welcher Reihenfolge was importiert wird.
Will man es wirklich austauschbar machen, dann sollte der Import so aussehen:
bzw.
Dann ist klar, welches Label benutzt wird. Noch besser ist es aber
zu benutzen, dann kann man nämlich wählen, ob man ttk.Label oder tk.Label schreibt.
`mainloop` ist eine ganz normale Methode, die intern eine Endlosschleife enthält, so dass sie erst zurückkehrt, wenn auch das Fenster wieder geschlossen wird. Dort wird eben auf Maus-, Tastatur- und andere Ereignisse gewartet, und diese dann verarbeitet.
Re: ttk buttons/widget states
Verfasst: Freitag 13. August 2021, 22:24
von __blackjack__
@blackdiamont: Prozedural oder OOP ist keine sinnvolle Unterscheidung in PHP oder Python weil auch OOP hier letztlich prozeduralen Code enthält. Da muss man schon eine Sprache wie Io nehmen, oder Smalltalk und sich dort mit prozeduralem Code zurückhalten.
In Python kann man sich bei Tk (und den meisten anderen GUI-Rahmenwerken) eigentlich gar nicht gegen OOP entscheiden. Andererseits sollte man keine Klassen für Dinge schreiben die mit Funktionen ausgedrückt werden können, denn nicht die ``class``-Anweisung macht eine Klasse zu einer Klasse, sondern der Inhalt einer Klasse bestimmt, ob das tatsächlich eine Klasse ist, oder nur umständlich verkleidete Funktionen. So wie Du das formulierst, klingt das als müsste man sich zwischen Funktionen und Klassen entscheiden, und müsste bei OOP dann alles so zwanghaft in Klassen stopfen wie bei Java.
Anderseits kann man in Python gar nicht ohne Objekte, denn *alles* was man an einen Namen binden kann, ist in Python ein Objekt. Auch Module, Funktionen, und Klassen beispielsweise.
Re: ttk buttons/widget states
Verfasst: Samstag 14. August 2021, 09:39
von blackdiamont
@Sirius3
Danke dir für's Aufklären

So langsam verstehe ich, wie es funktioniert. Ich werde mir lokal mal ein paar Beispiele anschauen und versuchen selbst was zu Basteln.
Komme wohl nicht darum den "schlechten" Code, komplett zu Verbessern.
@__blackjack__
Guter Punkt. Ich sehe teilweise PHP-Code der 90% Prozedural und 10% OOP hat (Schulaufgaben z.b.), wo ich den Sinn dahinter einfach nicht verstehe.
Mit OOP tue ich mich ehrlich gesagt noch etwas Schwer, daher bin ich bei PHP auch noch dabei (solange ich es nur für mich selbst Progge). Die Vorteile sind mir Bekannt und es ist auch interessant soweit
__blackjack__ hat geschrieben: Freitag 13. August 2021, 22:24
denn nicht die ``class``-Anweisung macht eine Klasse zu einer Klasse, sondern der Inhalt einer Klasse bestimmt, ob das tatsächlich eine Klasse ist, oder nur umständlich verkleidete Funktionen.
Gut zu wissen, darauf habe ich noch nie Geachtet.
Jedenfalls Danke euch beiden vielmals für eure Zeit etc

Habe jetzt einiges auf der ToDo
