Tkinter.Text "read-only"...

Fragen zu Tkinter.
Antworten
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hab noch mal einige änderungen vorgenommen. Mit https://github.com/jedie/DragonPy/commi ... fa2400b2d0 wird nun Zeichen für Zeichen übertragen.
Nun macht das "Echo" auch sinn, weil ich es so gemacht habe, das nicht direkt in geschrieben wird. Allerdings ist das IMHO unschön gelöst:

Ich möchte Text darstellen, den der User allerdings nicht direkt eingeben kann, sondern nur Programmseitig.

Ähnlich wie ein Terminalfenster/Konsole in dem der User was eingeben kann, aber die Zeichen der Eingabe immer vom Programm eingefügt wird.

z.Z. ist meine Lösung eine Tkinter.Text() Box. Fange die Eingabe-Zeichen mit self.root.bind("<Key>", self.event_key_pressed) ab und nehme da die einzelnen Zeichen in den buffer auf.
hier: https://github.com/jedie/DragonPy/blob/ ... #L244-L266

Eingefügt werden die Zeichen mit self.text.insert("end", char) hier: https://github.com/jedie/DragonPy/blob/ ... 09.py#L327

Damit nichts direkt in Tkinter.Text() geschrieben wird entziehe ich dem immer wieder den Fokus mit self.root.focus_set() hier: https://github.com/jedie/DragonPy/blob/ ... 09.py#L269

Dachte eigentlich ich könnte state=Tkinter.DISABLED nutzten. Aber dann funktioniert self.text.insert("end", char) nicht.
Auch das geht nicht:

Code: Alles auswählen

        self.text.state = Tkinter.NORMAL
        self.text.insert("end", char)
        self.text.state = Tkinter.DISABLED
        self.root.update()
Ideen?

EDIT: Ist für DragonPy -> http://www.python-forum.de/viewtopic.ph ... 19#p247319

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Ich hab leider von Tkinter null Ahnung, hatte aber ein ähnliches Problem für das Prototyping meines Javascript-xterm Klons unter Qt. Hatte da eine Weile mit QPlaintextEdit rum hantiert und mehr Ärger als Fortschritt - des Rästels Lösung war dann, das high-level Widget zu vergessen und auf QWidget (Basisklasse aller Qt-GUI-Klassen) zurückzufallen, alle KeyEvents selbst zu behandeln und das Widget selbst mit der Ausgabe zu zeichnen. Das eigenhändige Keymapping war nervig, aber einmal etabliert funktionierts prima.
Vielleicht ist das analog in Tkinter realisierbar, wobei für Dein Vorhaben die Textausgabe ja nur ein kleiner Vorgeschmack bzw. nebensächlich ist - spannend wirds mit Deiner "Treiber"-Implementation für die graphische Ausgabe des Gerätes ;)
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

@jens:
Mach mal

Code: Alles auswählen

self.text.config(state=Tkinter.NORMAL)
self.text.insert("end", char)
self.text.config(state=Tkinter.DISABLED)
:wink:
yipyip
BlackJack

Alternativ:

Code: Alles auswählen

self.text['state'] = Tkinter.NORMAL
...
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Sollten nicht alle drei Varianten das selbe machen?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

So, habe es ausprobiert. Meine Ursprüngliche geht nicht, eure beiden funktionieren. Also im Klartext:

Code: Alles auswählen

# geht nicht:
        self.text.state = Tkinter.NORMAL
        self.text.insert("end", char)
        self.text.state = Tkinter.DISABLED

# funktioniert:
        self.text.config(state=Tkinter.NORMAL)
        self.text.insert("end", char)
        self.text.config(state=Tkinter.DISABLED)

# funktioniert:
        self.text['state'] = Tkinter.NORMAL
        self.text.insert("end", char)
        self.text['state'] = Tkinter.DISABLED
Wobei IMHO die mittlere noch am saubersten ist.


Aber generell, ist das doch keine saubere Lösung. Welche Alternative gibt es?


EDIT: done: https://github.com/jedie/DragonPy/commi ... cf81ef065f

EDIT2: Lese gerade auf http://effbot.org/tkinterbook/text.htm :
By default, you can edit the text widget’s contents using the standard keyboard and mouse bindings. To disable editing, set the state option to DISABLED (but if you do that, you’ll also disable the insert and delete methods).
Es müsste noch ein anderen "state" geben, bei denen halt insert/delete nicht mit deaktiviert werden.

EDIT3: Ach, und weiter unten steht auch das:
To make the widget read-only, you can change the state option from NORMAL to DISABLED:

text.config(state=NORMAL)
text.delete(1.0, END)
text.insert(END, text)
text.config(state=DISABLED)

Note that you must change the state back to NORMAL before you can modify the widget contents from within the program. Otherwise, calls to insert and delete will be silently ignored.
/me RTFM :roll:

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten