Seite 1 von 2
Button event auslösen solange linke Maustaste gedrückt ist
Verfasst: Donnerstag 13. November 2008, 20:29
von loggod
hi Zusammen.
ich bin Anfänger was Python Programmierung angeht. Ich hoffe Ihr könnt mir ein wenig unter die Arme greifen.
Ich versuche eine Art 'Steuerkreuz' zu programmieren, bei dem solange etwas passiert solange, man mit dem Mauszeiger auf dem entsprechenden Button klickt und die linke Maustaste dabei gedrückt hält.
ein grober Rumpf wäre etwas in der Art:
Code: Alles auswählen
#! /usr/bin/env python
# -*- coding: utf-8
import Tkinter as tk
class navpad(object):
def __init__(self):
self.mainForm = tk.Tk()
self.mainFrame = tk.Frame (self.mainForm)
self.mainFrame.grid(row=1,column=1)
self.buttonNameHL = tk.Button(self.mainFrame,text='HL',command=lambda:self.send('hoch links'))
self.buttonNameHL.grid(row=1,column=1,sticky='W')
self.buttonNameHO = tk.Button(self.mainFrame,text='HO',command=lambda:self.send('hoch'))
self.buttonNameHO.grid(row=1,column=2,sticky='N')
self.buttonNameHR = tk.Button(self.mainFrame,text='HR',command=lambda:self.send('hoch rechts'))
self.buttonNameHR.grid(row=1,column=3,sticky='E')
self.buttonNameLI = tk.Button(self.mainFrame,text='LI',command=lambda:self.send('links'))
self.buttonNameLI.grid(row=2,column=1,sticky='W')
self.buttonNameRE = tk.Button(self.mainFrame,text='RE',command=lambda:self.send('rechts'))
self.buttonNameRE.grid(row=2,column=3,sticky='E')
self.buttonNameRL = tk.Button(self.mainFrame,text='RL',command=lambda:self.send('runter links'))
self.buttonNameRL.grid(row=3,column=1,sticky='W')
self.buttonNameRU = tk.Button(self.mainFrame,text='RU',command=lambda:self.send('runter'))
self.buttonNameRU.grid(row=3,column=2,sticky='S')
self.buttonNameRR = tk.Button(self.mainFrame,text='RR',command=lambda:self.send('runter rechts'))
self.buttonNameRR.grid(row=3,column=3,sticky='E')
self.mainForm.mainloop()
def send(self,name):
print name
navpad()
... nur halt eben mit der angesprochenen Funktionalität. Könnt Ihr mir dabei helfen ?
Ich bin für alle Tips und Anregungen dankbar.
Gruß,
loggod
Verfasst: Donnerstag 13. November 2008, 20:49
von numerix
Ich schlage vor, dass du dir das Kapitel "Event-handling in Tkinter" einmal zu Gemüte führst. Eine gute Übersicht findest du hier:
http://infohost.nmt.edu/tcc/help/pubs/t ... vents.html
Ich denke, dann wirst du die Lösung selbst entwickeln können.

Verfasst: Freitag 14. November 2008, 11:28
von loggod
Hi Numerix,
vielen Dank erst mal für den guten Link...Ist auf jedenfall in meinen Favoriten gelandet
...aber folgendes Problem: wenn ich von der Auflistung in
http://infohost.nmt.edu/tcc/help/pubs/t ... types.html ausgehe sehe ich nicht wie ich z.B ein
"<Button-1 _ is _ currently_Klicked_oder_irgendwas_in_der_Art>" event abfragen kann, weil es anscheinend nicht existiert. Es gibt ja nur "<Button>" und "<ButtonRelease>".
"<ButtonRelease>" könnte ich für eine Abbruch Bedingung nutzen um einen
Thread zu stoppen der angestoßen wird, nachdem man die Maustaste gedrückt gehalten hatte. Fehlt mir nur noch die entsprechende 'Bedingung' um den Thread anzustoßen.
"<Button>" implementiert ja nur das 'klicken' und anschließende 'loslassen' der Maustaste. Ich bräuchte aber halt eben nur das 'klicken'.
Einen eigenen event definieren? evtl. mit .char ?
Ausgehend von
http://infohost.nmt.edu/tcc/help/pubs/t ... dlers.html
...Kann mann einen Mausklick als regulären ASCII Code darstellen ?
Was ich schon im ersten post geschrieben habe bleibt....Ich bin für jeden Tip dankbar
Gruß,
loggod
Verfasst: Freitag 14. November 2008, 11:32
von wuf
Hallo loggod
ch versuche eine Art 'Steuerkreuz' zu programmieren, bei dem solange etwas passiert solange, man mit dem Mauszeiger auf dem entsprechenden Button klickt und die linke Maustaste dabei gedrückt hält.
Ich verstehe dein Funktionsbeschrieb leider nicht so richtig.
a) Ich nehme an du aktivierst die gewünschte Schaltfläche auch mit der linken Maustaste.
b) 'solange etwas passiert' ? Was meinst du mit passiert. Ich nehme an das etwas passiert solange die Schaltfläche aktiviert ist.
c) Beim loslassen der linken Maustaste (bzw. deaktivieren der Schaltfläche) passiert nichts mehr bzw. ist der Prozess beendet.
Könntest du den Funktionsablauf besser beschreiben.
Gruss wuf

Verfasst: Freitag 14. November 2008, 11:39
von loggod
Hi wuf,
es soll in etwa wie der cursor block auf der Tastatur funktionieren. Also:
z.B 4 Buttons: Hoch, Runter, Rechts, Links ... und es soll sollange 'Runter' mit print ausgegeben werden, sollange mann die Cursortaste ' Runter' gedrückt hält. Erst wenn mann sie wieder loslässt soll die Ausgabe aufhören.
Denkbar wäre auch ähnlich wie bei einem gamepad oder Joystick z.B einen Punkt o.ä. über ein Canvas zu 'lenken' etc.
Gruß,
loggod
Verfasst: Freitag 14. November 2008, 12:03
von wuf
Hallo loggod
Da könntest du zum Beispiel den '<Button-1>' und 'ButtonRelease-1>' Event an jede eingesetzte Schaltfläche binden. Angenommen die Schaltflache 'HL':
Code: Alles auswählen
self.buttonNameHL.bind('<Button-1>', self.button1_press)
self.buttonNameHL.bind('<ButtonRelease-1>', self.button1_release)
mit der Methode:
Kannst du eine Flag-Variable auf 'True' setzen und mit der Methode:
diese Flag-Variable wieder auf 'False' setzen.
Für die Auswertung musst du dann nur die Flag-Variable auf ihren Zustand prüfen.
Gruss wuf

Verfasst: Freitag 14. November 2008, 12:35
von wuf
Hallo loggod
Hier noch eine andere Variante.
Ereignisse der linken Maustaste an die Schaltfläche binden mit lambda:
Code: Alles auswählen
self.buttonNameHL.bind('<Button-1>',
lambda event, name='hoch': self.button1_press(event, name))
self.buttonNameHL.bind('<ButtonRelease-1>',
lambda event, name='hoch': self.button1_release(event, name))
Methode für Schalfläche 'drücken':
Code: Alles auswählen
def button1_press(self, event, name):
"""Schaltflaeche mit linker Maustaste gedruekt"""
self.flag = True
print 'Schaltfläche:', name, self.flag
Methode für Schalfläche 'loslassen':
Code: Alles auswählen
def button1_release(self, event, name):
"""Schaltflaeche mit linker Maustaste losgelassen"""
self.flag = False
print 'Schaltfläche:', name, self.flag
Die Button-Option 'command' braucht es nicht mehr.
Gruss wuf

Verfasst: Freitag 14. November 2008, 12:37
von loggod
Hi wuf,
danke für den Ansatz. Ich werde das mal so implementieren
Gruß,
loggod
Verfasst: Freitag 14. November 2008, 13:10
von burli
Hi loggod,
das was du möchtest ist ein Zustand, kein Event. Ein Event signalisiert dir lediglich das sich zb ein Zustand geändert hat. In diesem Fall zb MouseButtonClicked und MouseButtonReleased.
Aus diesen beiden Events musst du den Zustand des Mousebuttons sozusagen selbst ermitteln indem du eine Variable, zb MouseButtonHold, bei dem Event MouseButtonClicked auf TRUE setzt und beim Event MouseButtonReleased wieder auf False.
Vielleicht bietet Tkinter so eine Variable auch schon von sich aus.
Verfasst: Freitag 14. November 2008, 13:56
von yipyip
Hallo loggod,
bin auch der Meinung, dass man sich den
Zustand des 'Gedrückthaltens' aus den Events
'Button-Pressed' und 'Button-Release'
zusammenbasteln muss.
Das ist aber gar nicht so schwer.
Hab' hier mal 2 Demos für dich gemacht,
zwar mit einem etwas anderen Thema, aber
hoffentlich mit der von Dir gewünschten Funktionalität.
1)
http://paste.pocoo.org/show/91140/
Hier wird mit der after() Methode eine Schleife für
den Zustand 'Pressed' initiiert.
(s.a.
http://infohost.nmt.edu/tcc/help/pubs/t ... ersal.html)
2)
http://paste.pocoo.org/show/91141/
Hier wird die mainloop() explizit durch eine Schleife ersetzt.
Das ist wohl eher unüblich, aber falls man mal
einen Flugsimulator oder Ego-Shooter mit Tkinter schreiben will...

yipyip
Verfasst: Freitag 14. November 2008, 15:49
von wuf
Hallo loggod
Ich möchte mich den Super-Demos von 'yipyip' anschliessen. Habe die Erstellung deines Navigations-Widget noch ein bisschen automatisiert und folgendes zusammengeschmiedet.
[Code
ausgelagert]
Hier noch das dir vertraute Bildchen:
Das ganze soll dich nicht verwirren vielleicht kannst du etwas avon gebrauchen. Projekte können auf 100 verschiedene Arten gelöst werden. Eventuell haben auch noch andere Forummitglieder welche Ideen.
Gruss aus der Tk-Komponentenschmiede wuf

Verfasst: Freitag 14. November 2008, 17:12
von yipyip
Ups, bei der 2. Demo war ein
"self.canvas.delete('all')" zuviel,
bitte bei
Paste Details -> show paste tree
die neueste Version nehmen.
Verfasst: Freitag 14. November 2008, 21:38
von wuf
Hallo loggod
Hier noch die grafische Variante des des Navigations-Widgets:
[Code
ausgelagert]
Gruss wuf

Verfasst: Freitag 14. November 2008, 22:08
von numerix
@wuf: Wie hast du die Buttons so schick hinbekommen?
Waren das Fertigprodukte oder hast du die selbst erstellt? Durch die Beschränkung auf das gif-Format ist es ja nicht so einfach, wirklich gut aussehende Buttons zu basteln.
Verfasst: Samstag 15. November 2008, 00:22
von wuf
Hallo numerix
Nein die Bildchen habe ich nicht selber konstruiert Habe sie im Internet gefunden beim suchen nach frei verfügbare Icons. Aber GIMP hat noch einige Zusätze (Plugin's) die es einem ermöglichen eigene Kunstwerke zu erstellen und als .gif's zu exportieren.
OK. Gruss wuf

Verfasst: Samstag 15. November 2008, 00:37
von wuf
Hallo loggod
Noch eine Frage zum Code-Snippet, welches du in deinem ersten Post vorgestellt hast. Ist dies dein Original Skript? Weil da hat es Einrück-Fehler drin. Ist dies eventuell beim transverieren ins Forum passiert?
Noch ein Tipp:
Bei der Konfiguration der Grid-Layout-Manager Anweisungen würde ich die 'sticky'-Option mit dem Wert 'nesw' belegen damit das betreffende Button-Widget das ganze Grid-Feld ausfüllt.
Gruss wuf

Verfasst: Samstag 15. November 2008, 06:29
von numerix
wuf hat geschrieben:Aber GIMP hat noch einige Zusätze (Plugin's) die es einem ermöglichen eigene Kunstwerke zu erstellen und als .gif's zu exportieren.
Das Problem ist auch weniger das Erstellen optisch ansprechender Buttons/Icons, sondern der Export in das GIF-Format mit seiner Beschränkung auf 256 Farben. Ich habe schon manches schöne Icon als png gehabt und nach der Konvertierung nach gif konnte man es wegschmeißen, weil z.B. sanfte Kantenübergänge und Farbverläufe nicht mehr so fein dargestellt werden konnten.
Verfasst: Samstag 15. November 2008, 10:58
von wuf
Hallo numerix
Hast du schon eimal versucht das PIL-Packet für die Darstellung von Bilder einzusetzen. Zum Beispiel für ein Icon im .png-Format. Das PIL-Packet enthält ein Modul 'ImageTk' die sich hierfür eignet.
Hier ein kleines Testprogramm:
Code: Alles auswählen
import Tkinter as tk
import Image
import ImageTk
test_window = tk.Tk()
pil_icon = Image.open("archive.png")
pil_icon_1 = pil_icon.rotate(45)
pil_icon_2 = pil_icon.resize((70,70))
tk_icon = ImageTk.PhotoImage(pil_icon)
tk_icon_1 = ImageTk.PhotoImage(pil_icon_1)
tk_icon_2 = ImageTk.PhotoImage(pil_icon_2)
button = tk.Button(test_window, image=tk_icon)
button.pack(side='left')
button = tk.Button(test_window, image=tk_icon_1)
button.pack(side='left')
button = tk.Button(test_window, image=tk_icon_2)
button.pack(side='left')
test_window.mainloop()
Der Output für mein Bildchen 'archive.png':
Gruss wuf

Verfasst: Samstag 15. November 2008, 10:58
von Leonidas
numerix hat geschrieben:Export in das GIF-Format mit seiner Beschränkung auf 256 Farben.
True-Color GIFs anyone? (
Infos dazu)
Aber gut, davon abgesehen ist GIF sowieso am besten durch PNG zu ersetzen und damit hat es sich.
Verfasst: Samstag 15. November 2008, 11:10
von wuf
@Leonidas
Danke für den interessanten Link
In letzter Zeit häufen sich Post's die im gleichen Zeitfenster eintreffen.

Muss etwas mit der momentanen Planeten-Konstellation zu tun haben.
Gruss wuf
