Button-Event deaktivieren

Plattformunabhängige GUIs mit wxWidgets.
Antworten
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Hallo Community

ich hab ein kleines Problem!

Wenn man auf einen Button (Start) drückt

wird eine test-for schleife ausgelöst die in eine TextCtrl die Zahlen 1-9000 ausgibt! und self.button1.Disable() wird ausgeführt, bis die schleife zu ende ist!, allerdings wenn man in der Zwischenzeit den Button nochmal drückt, wird trotzdem ein Event ausgelöst => die Schleife zählt danach noch einmal, wie kann ich dass umgehen?

mfg
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo David

Kannst du die test-for Schleife nicht umgehen während sie am zählen ist? Mit einer einfachen if-Anweisung die eine Flag kontrolliert die besagt, dass ein laufender test-for-Prozess noch nicht beendet ist.

Gruss wuf :wink:
Take it easy Mates!
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

schon probiert

Code: Alles auswählen

        self.button.Disable()
        if self.pressed:
            return None
       self.pressed = True
        for i in range(9000):
            self.textctrl1.WriteText('Hallo %s\n' % i)
        self.pressed = False
        self.button.Enable()
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

..... Kannst du evt. noch das folgende ausprobieren:

Code: Alles auswählen

        event.Skip()
        
        self.button.Disable() 
        if self.pressed: 
            return None 
        self.pressed = True 
        for i in range(9000): 
            self.textctrl1.WriteText('Hallo %s\n' % i) 
        self.pressed = False 
        self.button.Enable()


Gruss wuf :wink:
Take it easy Mates!
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

nein leider nicht
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Kannst du evt. ein Code-Schnippsel zur Verfügung stellen um damit herumzuspielen? Oder ist es geheim?
Take it easy Mates!
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Geheim^^

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-

import hashlib
import sys
import os
import time
import wx

class Main(wx.Frame):
    def __init__ (self, parent, id, title,):
        wx.Frame.__init__(self, parent, id, title, size=(440, 250), style=wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX)
        
        self.md5h = False
        self.sha1h = False
        self.sha224h = False
        self.sha256h = False
        self.sha384h = False
        self.sha512h = False
        
        self.path = ''
        
        self.pressed = False
        
        panel = wx.Panel(self, -1)
        
        vbox = wx.BoxSizer(wx.VERTICAL)
        
        hbox1 = wx.BoxSizer(wx.HORIZONTAL)
        hbox1.Add(wx.StaticText(panel, 11, 'tesText:'), 0, wx.ALL, 10)
        hbox1.Add(wx.TextCtrl(panel, 12, size=(200, -1)), 0, wx.EXPAND | wx.ALL, 10)
        self.button = wx.Button(panel, 13, 'LookUp')
        hbox1.Add(self.button, 0, wx.TOP, 10)
        hbox1.Add(wx.Button(panel, 14, 'GetDir'), 0, wx.TOP, 10)
        vbox.Add(hbox1)
        
        
        hbox2 = wx.BoxSizer(wx.HORIZONTAL)
        hbox2.Add(wx.CheckBox(panel, 21, 'MD5'), 0, wx.EXPAND | wx.ALL, 10)
        hbox2.Add(wx.CheckBox(panel, 22, 'SHA1'), 0, wx.EXPAND | wx.ALL, 10)
        hbox2.Add(wx.CheckBox(panel, 23, 'SHA224'), 0, wx.EXPAND | wx.ALL, 10)
        hbox2.Add(wx.CheckBox(panel, 24, 'SHA256'), 0, wx.EXPAND | wx.ALL, 10)
        hbox2.Add(wx.CheckBox(panel, 25, 'SHA384'), 0, wx.EXPAND | wx.ALL, 10)
        hbox2.Add(wx.CheckBox(panel, 26, 'SHA512'), 0, wx.EXPAND | wx.ALL, 10)
        vbox.Add(hbox2)
        
        hbox3 = wx.BoxSizer(wx.HORIZONTAL)
        self.textctrl1 = wx.TextCtrl(panel, 31, size=(230, 115), style=wx.TE_MULTILINE | wx.TE_READONLY)
        hbox3.Add(self.textctrl1, 0, wx.EXPAND | wx.ALL, 10)
        self.textctrl2 = wx.TextCtrl(panel, 32, size=(160, 115), style=wx.TE_MULTILINE | wx.TE_READONLY)
        hbox3.Add(self.textctrl2, 0, wx.EXPAND | wx.ALL, 10)
        vbox.Add(hbox3)
        
        panel.SetSizer(vbox)
        
        self.Bind(wx.EVT_BUTTON, self.OnLookUp, id=13)
        self.Bind(wx.EVT_BUTTON, self.OnGetDir, id=14)
        
        self.Bind(wx.EVT_CHECKBOX, self.md5, id=21)
        self.Bind(wx.EVT_CHECKBOX, self.sha1, id=22)
        self.Bind(wx.EVT_CHECKBOX, self.sha224, id=23)
        self.Bind(wx.EVT_CHECKBOX, self.sha256, id=24)
        self.Bind(wx.EVT_CHECKBOX, self.sha384, id=25)
        self.Bind(wx.EVT_CHECKBOX, self.sha512, id=26)
                
        
        self.Centre()
        self.Show(True)
        
    def OnLookUp(self, event):
        event.Skip()
        self.button.Disable()
        for i in range(9000):
            #print 'MD5 =', self.md5h
            self.textctrl1.WriteText('Hallo %s\n' % i)
        self.pressed = False
        self.Enable()
    def OnGetDir(self, event):
        dlg = wx.DirDialog(self, "Choose a directory:", style=wx.DD_DEFAULT_STYLE)
        if dlg.ShowModal() == wx.ID_OK:
            self.path = dlg.GetPath()
        dlg.Destroy()
 

    def md5(self, event):
        pass
    def sha1(self, event):
        pass
    def sha224(self, event):
        pass
    def sha256(self, event):
        pass
    def sha384(self, event):
        pass
    def sha512(self, event):
        pass
Das ganze soll mal in ferner Zukunft eine txt-datei einlesen und in die ausgewählten hashes hashen und in eine nue txt-datei schreiben

import sys, os, time (werden in ferner Zukunft gebraucht)

mfg
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo Dav1d

Danke für das Schippet. Kann dir leider noch keine Lösung anbieten. Da ich leider noch nicht ein totaler wxPython-Insider bin muss ich mich noch näher mit der Event-Mistery von wxPython beschäftigen. Scheinbar werden die gegebenen Klicks der Schaltfläche auf einem Stack abgelegt und nacheinander abgearbeitet. Wie nun nach einem Klick verhindert wird, dass ein weiterer akzeptiert wird habe ich noch nicht herausgefunden. Vielleicht kann uns hier ein wxPython-Insider helfen.

Gruss wuf :wink:
Take it easy Mates!
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Danke für die Hilfe,
Scheinbar werden die gegebenen Klicks der Schaltfläche auf einem Stack abgelegt und nacheinander abgearbeitet.
das war auch meine Vermutung

das einzigste was mir als Lösung einfällt ist bzw sind Threads (-.-) hab keine Ahnung von Threads

Ansatz

die For-Schleife in nem Thread laufen lassen, falls der Button geklickt wird, dann so ne Art

if thread.running():
return None
else:
start.NewThread()

Ich hoffe ein eingefleischter wxPython-Kenner kann mir, bzw uns weiterhelfen

mfg

//Edit: Dass es nicht zu verwirrungen kommt was

Code: Alles auswählen

        self.md5h = False
        self.sha1h = False
        self.sha224h = False
        self.sha256h = False
        self.sha384h = False
        self.sha512h = False
bringt hier der Sinn der Sache

Code: Alles auswählen

    def md5(self, event):
        self.md5h = event.IsChecked()
    def sha1(self, event):
        self.sha1h = event.IsChecked()
    def sha224(self, event):
        self.sha224h = event.IsChecked()
    def sha256(self, event):
        self.sha256h = event.IsChecked()
    def sha384(self, event):
        self.sha384h = event.IsChecked()
    def sha512(self, event):
        self.sha512h = event.IsChecked()
bringt insofern was, wenn man die Buttons von Angang an nicht verändertt brauchen sie zum Prüfen einen Wert der wird dann damit zugewisen
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo Dav1d

Kannst du einmal das folgende Snippet ausprobieren:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-

import hashlib
import sys
import os
import time
import wx

class Main(wx.Frame):
    def __init__ (self, parent, id, title,):
        wx.Frame.__init__(self, parent, id, title, size=(440, 250), style=wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX)
       
        self.md5h = False
        self.sha1h = False
        self.sha224h = False
        self.sha256h = False
        self.sha384h = False
        self.sha512h = False
       
        self.path = ''
       
        self.pressed = False
       
        panel = wx.Panel(self, -1)
       
        vbox = wx.BoxSizer(wx.VERTICAL)
       
        hbox1 = wx.BoxSizer(wx.HORIZONTAL)
        hbox1.Add(wx.StaticText(panel, 11, 'tesText:'), 0, wx.ALL, 10)
        hbox1.Add(wx.TextCtrl(panel, 12, size=(200, -1)), 0, wx.EXPAND | wx.ALL, 10)
        self.button = wx.Button(panel, 13, 'LookUp')
        hbox1.Add(self.button, 0, wx.TOP, 10)
        hbox1.Add(wx.Button(panel, 14, 'GetDir'), 0, wx.TOP, 10)
        vbox.Add(hbox1)
       
       
        hbox2 = wx.BoxSizer(wx.HORIZONTAL)
        hbox2.Add(wx.CheckBox(panel, 21, 'MD5'), 0, wx.EXPAND | wx.ALL, 10)
        hbox2.Add(wx.CheckBox(panel, 22, 'SHA1'), 0, wx.EXPAND | wx.ALL, 10)
        hbox2.Add(wx.CheckBox(panel, 23, 'SHA224'), 0, wx.EXPAND | wx.ALL, 10)
        hbox2.Add(wx.CheckBox(panel, 24, 'SHA256'), 0, wx.EXPAND | wx.ALL, 10)
        hbox2.Add(wx.CheckBox(panel, 25, 'SHA384'), 0, wx.EXPAND | wx.ALL, 10)
        hbox2.Add(wx.CheckBox(panel, 26, 'SHA512'), 0, wx.EXPAND | wx.ALL, 10)
        vbox.Add(hbox2)
       
        hbox3 = wx.BoxSizer(wx.HORIZONTAL)
        self.textctrl1 = wx.TextCtrl(panel, 31, size=(230, 115), style=wx.TE_MULTILINE | wx.TE_READONLY)
        hbox3.Add(self.textctrl1, 0, wx.EXPAND | wx.ALL, 10)
        self.textctrl2 = wx.TextCtrl(panel, 32, size=(160, 115), style=wx.TE_MULTILINE | wx.TE_READONLY)
        hbox3.Add(self.textctrl2, 0, wx.EXPAND | wx.ALL, 10)
        vbox.Add(hbox3)
       
        panel.SetSizer(vbox)
       
        self.Bind(wx.EVT_BUTTON, self.OnLookUp, id=13)
        self.Bind(wx.EVT_BUTTON, self.OnGetDir, id=14)
        self.Bind(wx.EVT_IDLE, self.OnIdle)
       
        self.Bind(wx.EVT_CHECKBOX, self.md5, id=21)
        self.Bind(wx.EVT_CHECKBOX, self.sha1, id=22)
        self.Bind(wx.EVT_CHECKBOX, self.sha224, id=23)
        self.Bind(wx.EVT_CHECKBOX, self.sha256, id=24)
        self.Bind(wx.EVT_CHECKBOX, self.sha384, id=25)
        self.Bind(wx.EVT_CHECKBOX, self.sha512, id=26)
               
       
        self.Centre()
        self.Show(True)
       
    def OnLookUp(self, event):

        self.pressed = True

    def OnIdle(self, event):

        if self.pressed:
            self.button.Disable()
            for i in range(1000):
                #print 'MD5 =', self.md5h
                self.textctrl1.WriteText('Hallo %s\n' % i)
            self.button.Enable()
            self.pressed = False

    def OnGetDir(self, event):
        dlg = wx.DirDialog(self, "Choose a directory:", style=wx.DD_DEFAULT_STYLE)
        if dlg.ShowModal() == wx.ID_OK:
            self.path = dlg.GetPath()
        dlg.Destroy()
 

    def md5(self, event):
        pass
    def sha1(self, event):
        pass
    def sha224(self, event):
        pass
    def sha256(self, event):
        pass
    def sha384(self, event):
        pass
    def sha512(self, event):
        pass 

app = wx.App(redirect=False)

main = Main(None, wx.ID_ANY, 'None')

app.MainLoop()
Bitte die Methode 'OnIdle' beachten.

Gruss wuf :wink:
Take it easy Mates!
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Nein leider nicht, ich denke weil der 2. Klick erst ausgeführt wird wenn alles andere beendet is, und dann is auch schon self.pressed wieder False

mfg
fhoech
User
Beiträge: 143
Registriert: Montag 9. April 2007, 18:26

Der ursprüngliche Codeschnipsel funktioniert bei mir zumindest teilweise unter Windows XP und Linux (openSUSE11), sprich Klicks auf den Button werden ignoriert solang OnLookUp läuft. Unter Linux wird allerdings der Button am Anfang nicht deaktiviert, und während die Schleife durchlaufen wird finden keine Fensterupdates statt wie unter XP (wobei die Fensterupdates unter XP auch aufhören, sobald man das Fenster verschiebt).
Grundsätzlich sollte man sich nicht drauf verlassen, dass Änderungen am GUI sofort ausgeführt werden, sondern Teil des Eventhandlings sind, und das für GUI-Updates zuständige EVT_PAINT wird normalerweise erst abgearbeitet, nachdem der aktuelle Event-Handler (in dem Fall OnLookUp) durch ist.
Eine Lösung, welche die GUI nicht blockiert, könnte so aussehen (allerdings dauert es so auch deutlich länger, den Wertebereich zu durchlaufen):

Code: Alles auswählen

    def OnLookUp(self, event):
        event.Skip()
        self.button.Disable()
        self.iterationcount = 0
        self.Bind(wx.EVT_IDLE, self.OnIdle)
    
    def OnIdle(self, event):
        if self.iterationcount < 1000:
            self.textctrl1.AppendText('Hallo %s\n' % self.iterationcount)
            self.iterationcount += 1
            event.RequestMore(True)
        else:
            self.Unbind(wx.EVT_IDLE)
            self.button.Enable()
(Statt WriteText habe ich AppendText genommen, da so der Text immer nach der letzten Zeile eingefügt wird, statt an der aktuellen Position der Einfügemarke)
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Cool,
es funktioniert, danke

das beste is die Geschwindigkeit is die Selbe :)

einmal (bei meiner alten Methode) : 6.29482119412
jetzt deine (die neue Metheode) : 6.30684332716
lol, eine reiner Konsolendurchlauf (mit print) braucht: 1.8499609661

bei einer schleife von 9000 ( for i in range(9000) )

mfg
Antworten