Zeit zwischen Drücken und Loslassen eines Knopfes

Fragen zu Tkinter.
Antworten
theoS
User
Beiträge: 108
Registriert: Dienstag 5. November 2019, 21:44

Hallo.
Habe eine Oberfläche für einen PI geschaffen, die funktioniert gut, allerdings soll das das Einzige sein, was man in dem Touchscreen machen/sehen kann.
Um den PI irgendwann mal runterfahren zu können habe ich mir gedacht, das ginge entweder durch Drücken zweier verschiedener Knöpfe gleichzeitig, da versage ich aber komplett.
Dann dachte ich mir, ich werte die Zeit aus wenn ein Knopf niedergdrückt wird und dann wieder losgelassen.
Das habe ich jetzt zwar nicht für einen einzelnen geschafft, aber für alle, was jetzt erst mal egal ist.
Habe nämlich ein anderes Problem.
Kann mir zwar die Zeiten anzeigen lassen, die werden vermutlich auch zurückgegeben von ihrer Funktion, aber mir fällt jetzt nichts mehr ein, wie ich die Rückgabewerte denn dann auswerten kann.
Kann mir da jemand was dazu erklären?

Hab den Code mal ein wenig vereinfacht, da hängt normal noch mehr dran.
(den Triple-Click hab ich mir noch aufgehoben als evtl. Notlösung)

Code: Alles auswählen

#!/usr/bin/env python3
# -*- coding: utf8 -*-

import tkinter as tk
from functools import partial
import time
from datetime import datetime as DateTime


CONFIG =[
    (12, 6, 'Beispiel', 'Bsp 001'),
    (623, 4, 'Beispiel', 'Bsp 002' ),
    (91, 5, 'Beispiel', 'Bsp 003' ),
    (625, 7, 'Beispiel', 'Bsp 004'),
    (17, 8, 'Beispiel', 'Bsp 005'),
    (627, 413, 'Beispiel', 'Bsp 006'),
    (624, 1, 'Beispiel', 'Bsp 007'),
    (13, 9, 'Beispiel', 'Bsp 008')
    ]

def on_click(zeile):   
    print(zeile[0])
    
def stopp_druck(event):
    
    zeit_drueck = time.time()
    print("stopp_druck", zeit_drueck)    
    return zeit_drueck

def start_druck(event):
    
    zeit_los = time.time()    
    print("start_druck", zeit_los)
    return zeit_los

def dreimal(event):
    print("triple-Druck")


def main():

    root = tk.Tk()
    root.title("Auswahl der Label")
    root.config(background="#f2c618")
    button_frame = tk.Frame(root, width=1200, height=400)
    button_frame.grid(row=0, column=0, padx=10, pady=3)

    
    for index, entry in enumerate(CONFIG):
        row_index, column_index = divmod(index, 4)
        
        tk.Button(
            button_frame,
            text="{}\n{}".format(entry[1], entry[2]),
            bg="#f2c618",
            width=15,
            height=10,
            command=partial(on_click, entry),            
            ).grid(row=row_index, column=column_index, padx=0, pady=0)
    root.bind('<Triple-1>', dreimal)
    root.bind('<ButtonPress-1>', start_druck)
    root.bind('<ButtonRelease-1>', stopp_druck)
    
    if  zeit_los - zeit_drueck < 5000:
        print("weniger als 5000")
    else:
        print("jetzt würde er ausgeschaltet")

    
    root.mainloop()

        
if __name__ == '__main__':

    main()
Sirius3
User
Beiträge: 18289
Registriert: Sonntag 21. Oktober 2012, 17:20

Zu dem Zeitpunkt wo zeit_los - zeit_drueck geprüft wird, hatte noch niemand die Gelegenheit irgendeinen Knopf zu drücken.
Wenn man Zustand (Zeitpunkt des Drückens) speichern will, braucht man eine Klasseninstanz, und das ist bei jedem nicht-trivialen GUI-Programm nötig.
Der Rückgabewert eines Callbacks wird ignoriert.
Statt time.time solltest Du time.monotonic benutzen.

Code: Alles auswählen

#!/usr/bin/env python3
# -*- coding: utf8 -*-

import tkinter as tk
from functools import partial
import time
from datetime import datetime as DateTime


CONFIG =[
    (12, 6, 'Beispiel', 'Bsp 001'),
    (623, 4, 'Beispiel', 'Bsp 002' ),
    (91, 5, 'Beispiel', 'Bsp 003' ),
    (625, 7, 'Beispiel', 'Bsp 004'),
    (17, 8, 'Beispiel', 'Bsp 005'),
    (627, 413, 'Beispiel', 'Bsp 006'),
    (624, 1, 'Beispiel', 'Bsp 007'),
    (13, 9, 'Beispiel', 'Bsp 008')
]

class MainWindow(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Auswahl der Label")
        self["background"] = "#f2c618"
        button_frame = tk.Frame(self, width=1200, height=400)
        button_frame.grid(row=0, column=0, padx=10, pady=3)    
        for index, entry in enumerate(CONFIG):
            row_index, column_index = divmod(index, 4)
            tk.Button(
                button_frame,
                text="{}\n{}".format(entry[1], entry[2]),
                bg="#f2c618",
                width=15,
                height=10,
                command=partial(self.on_click, entry),            
                ).grid(row=row_index, column=column_index, padx=0, pady=0)
        self.bind('<ButtonPress-1>', self.start_druck)
        self.bind('<ButtonRelease-1>', self.stopp_druck)
        self.knopf_drueck_zeit = None

    def on_click(self, zeile):
        print(zeile[0])
    
    def start_druck(self, event):    
        self.knopf_drueck_zeit = time.monotonic()
        print("stopp_druck", self.knopf_drueck_zeit)    

    def stopp_druck(self, event):
        knopf_loslass_zeit = time.monotonic()    
        print("start_druck", knopf_loslass_zeit)
        if knopf_loslass_zeit - self.knopf_drueck_zeit > 5:
            print("Neustart")

def main():
    root = MainWindow()
    root.mainloop()

        
if __name__ == '__main__':
    main()
theoS
User
Beiträge: 108
Registriert: Dienstag 5. November 2019, 21:44

Klassenprogrammierung... ich habs befürchtet.
In das Thema muss ich mich noch mal kräftig einlesen.
Aber, mir ist es immerhin gelungen, die von dir erstellte Klasse in mein Projekt einzubinden.
Das funktioniert!
Mir ist es sogar schon gelungen, eine Messagebox einzubauen, die noch mal die Möglichkeit bietet zurückzugehen wenn man das versehentlich ausglöst hat.
Danke!!

Was ich da jetzt noch nicht so ganz checke ist jedenfalls der Aufruf von Funktionen. Hab die Click-Funktion beim Umsetzen in mein Projekt (da gibt sie 2 Parameter weiter) nicht hingekriegt und dann außerhalb der Klasse definiert, das ging dann. Inzwischen habe ich den Fehler dran gefunden und hab sie in die Klasse gebaut.
Ist so was dann egal? Die Click-Funktion löst ja nichts im Fenster selbst aus.
Was ist da besser? Oder ist das egal. (funktioniert hat beides)
theoS
User
Beiträge: 108
Registriert: Dienstag 5. November 2019, 21:44

Nachtrag: monotonic ist cool! Genau das was ich hier brauchte.
Antworten