Plenz Posted May 31, 2012 at 10:33 PM Posted May 31, 2012 at 10:33 PM Ich bin ein ziemlicher Python-Neuling und versuche mich jetzt mit Tkinter, weil es mir scheint, dass eine grafische Oberfläche mit Buttons deutlich weniger Code braucht als eine simple Tastendruck-Abfrage per Konsole. Leider habe ich mich im Dschungel der Objekte, Klassen und Instanzen verirrt. Insbesondere ist mir schleierhaft, was man in welcher Reihenfolge definieren bzw. programmieren muss. Als erster Gehversuch soll ein IO4-Eingang den Text eines Labels verändern, aber ich schaffe es nicht. Hier mal ein ganz grober Ablauf: from Tkinter import * ... UID_IO4 = "7Qo" # IO-4 Bricklet io4 = IO4(UID_IO4) # Create device object ipcon = IPConnection(HOST, PORT) # Create IP conn. to brick ipcon.add_device(io4) # Add device to IP conn. # Callback function for interrupts # Ja, etwas blöd so mitten drin, aber das gab die wenigesten Fehler def cb_interrupt(interrupt_mask, value_mask): if ((interrupt_mask == 4) & ((value_mask & 4) == 0)): print "EIN" # das funktioniert noch! App.anschlo("EIN") # das ist fehlerhaft # Enable interrupt io4.set_interrupt((1 << 2)|(1 << 3)) # Register callback for interrupts io4.register_callback(io4.CALLBACK_INTERRUPT, cb_interrupt) class App: def __init__(self, master): frame = Frame(master) frame.pack() self.anschl1 = Label(frame, text="x") self.anschl1.pack(side=LEFT) self.button = Button(frame, text="QUIT", command=self.ende) self.button.pack(side=LEFT) def anschlo(tx): self.anschl1.text = tx def ende(self): ipcon.destroy() print "IP destroyed." root.destroy() root = Tk() app = App(root) root.mainloop() Die Interrupt-Routine scheint das Label nicht zu kennen oder falsch anzusprechen oder... Ich würde mich freuen, wenn jemand dieses Programm ein wenig aufräumen würde. Quote
AuronX Posted June 1, 2012 at 06:54 AM Posted June 1, 2012 at 06:54 AM Deine def vom anschlo ist kaputt: def anschlo(tx): richtig wäre def anschlo(self, tx): Ich bin auch nie drauf klargekommen, dass man in python das self explizit als ersten Parameter mit übergibt ^^ Also das ist mira uch oft passiert P.S.: Ah okay, das war nur die Halbe Lösung ^^ Oben im Callback nutzt du ja App (großgeschrieben), das wäre dann vermutlich ein statischer Aufruf (bin mir unsicher), bei dem gäbe es aber kein self. Ich entwirr das ganze mal noch kurz in meinem Kopf und dann poste ich hier drunter neuen Code ^^ from Tkinter import * # ich habe mal zur Entwirrung alles sortiert (globals ganz oben, dann defs, dann class, dann main-code) # wenn das nen Unterschied macht muss es irgendwann zu Irritation kommen # lieber rechtzeitig vorbeugen app = None # der aktuelle Code braucht das als global (muss man in Python doch vorher definieren oder?) def cb_interrupt(interrupt_mask, value_mask): if ((interrupt_mask == 4) & ((value_mask & 4) == 0)): print "EIN" # das funktioniert noch! app.anschlo("EIN") # das sollte jetzt hoffentlich auch gehen class App: def __init__(self, master): frame = Frame(master) frame.pack() self.anschl1 = Label(frame, text="x") self.anschl1.pack(side=LEFT) self.button = Button(frame, text="QUIT", command=self.ende) self.button.pack(side=LEFT) def anschlo(self, tx): self.anschl1.text = tx def ende(self): ipcon.destroy() print "IP destroyed." root.destroy() UID_IO4 = "7Qo" # IO-4 Bricklet io4 = IO4(UID_IO4) # Create device object ipcon = IPConnection(HOST, PORT) # Create IP conn. to brick ipcon.add_device(io4) # Add device to IP conn. root = Tk() app = App(root) root.mainloop() # callback erst dann registrieren, wenn die Variable "app" auch gesetzt ist # sonst würde die "cb_interrupt" methode explodieren (viel Rauch und Schutt) io4.set_interrupt((1 << 2)|(1 << 3)) io4.register_callback(io4.CALLBACK_INTERRUPT, cb_interrupt) Dieser Code ist bei mir gerade rausgekommen und sollte laufen... hoffe ich ^^ DAs Problem ist, dass ich gar nicht so gut bin in Python. Normalerweise hätte ich dir auch dazu geraten, dass du die cb_interrupt-methode in deine App-Klasse hineinziehst, aber ich glaube nicht, dass das geht, weil ja der explizite self-parameter stören würde. In anderen Sprachen ginge das tatsächlich, hier hab ich gerade keine hübsche Idee. Deswegen auch app als globale Variable (nicht soooo toller Stil). Hoffe ich konnte helfen. Quote
Plenz Posted June 1, 2012 at 02:23 PM Author Posted June 1, 2012 at 02:23 PM Herzlichen Dank erst mal, ich werde das heute abend ausprobieren. Mir ist das alles ein Rätsel (von wegen "Python ist soooo einfach"), insbesondere denke ich, root.mainloop() soll m.W. eine Endlosschleife sein, in der das Programm quasi "gefangen" ist und nur noch auf Ereignisse (Interrupts) warten kann... wie zum Geier kann danach noch weiterer Code stehen und ausgeführt werden? Quote
AuronX Posted June 1, 2012 at 02:56 PM Posted June 1, 2012 at 02:56 PM Das liegt daran, dass ich eben ein Dummkopf bin Also wenn das ne Endlosschleife ist dann sollte der Code natürlich nochd avor sein. Aber auch NACHDEM app definiert wurde. Also genau zwischen diesen beiden Zeilen: app = App(root) root.mainloop() War mein Fehler ^^ Quote
M4ST3R Posted June 1, 2012 at 04:10 PM Posted June 1, 2012 at 04:10 PM Ja Python ist programmier technisch für Einsteiger gut aber ich glaube, wenn man GUI programmieren möchte gibt es besseres. Quote
Plenz Posted June 1, 2012 at 04:15 PM Author Posted June 1, 2012 at 04:15 PM Das liegt daran, dass ich eben ein Dummkopf bin Also wenn das ne Endlosschleife ist dann sollte der Code natürlich nochd avor sein. Aber auch NACHDEM app definiert wurde. Ich weiß nicht, ob das eine Endlosschleife ist, aber in dem Tutorial, wo ich das her habe, stand das so drin. Und der Rest ist bloß gesunder Menschenverstand. Aber jetzt wo du's sagst... in dem Beispiel von Tinkerforge gibt es keine Endlosschleife... das verstehe wer will... Quote
Plenz Posted June 1, 2012 at 04:38 PM Author Posted June 1, 2012 at 04:38 PM Ja Python ist programmier technisch für Einsteiger gut aber ich glaube, wenn man GUI programmieren möchte gibt es besseres. Wem sagt du das. Meine Lieblingssprache ist immer noch der BASIC-Dialekt "Rapid-Q", zwar veraltet und ungepflegt, läuft aber auch unter Win7, was will man mehr. Rapid-Q ist super für kleine Projekte, weil man die Form mit allen Elementen sowie den Programmcode in eine einzige Datei packen kann. Es ist nur nicht so extrem objektorientiert, und man kann wahrscheinlich keine Callbacks programmieren, aber mir würde das genügen, alles in einer einzigen Endlosschleife abzufragen. Ich bräuchte nur eine dafür geeignete DLL, dann wäre Python für mich gestorben. Quote
AuronX Posted June 1, 2012 at 05:35 PM Posted June 1, 2012 at 05:35 PM Sagen wir es so: GUI-Programmierung ist immer ziemlich übel, weil du neben der Programmiersprache auch gleich noch mittelgroße Frameworks und deren Konzepte mitverstehen musst. Allerdings gibt es auch schlanke GUIs, aber meist ist das nen Stück mehr Aufwand als ne Konsolenanwendung. @Plenz: was war der Grund warum du nicht einfach ne Konsolenanwendung gemacht hast? Du hattest am Anfang angedeutet, dass dir ne GUI leichter schien als ne Konsole Quote
M4ST3R Posted June 1, 2012 at 07:41 PM Posted June 1, 2012 at 07:41 PM Also wenn ich mir das bei Netbeans angucke ist das ziemlich einfach eine GUI zu basteln. Bei Bedarf mach ich n Video bzw suche eins raus Quote
Plenz Posted June 1, 2012 at 08:30 PM Author Posted June 1, 2012 at 08:30 PM @Plenz: was war der Grund warum du nicht einfach ne Konsolenanwendung gemacht hast? Du hattest am Anfang angedeutet, dass dir ne GUI leichter schien als ne Konsole Hatte ich oben schon erwähnt: es geht um die simpele Abfrage von Tasten. Einfach eine Schleife, in der pausenlos der Tastaturpuffer abgefragt wird, und wenn das "A" gedrückt wird, dann tu dies, und wenn "B" gedrückt wird, dann tu das. Ich habe mich dumm und dusselig gesucht nach so einem Code, aber nichts gefunden. Dagegen war das Beispiel für eine winzige Form mit einem Button, der per Klick eine Subroutine startet, völlig simpel und kurz. Das Problem war nur, die zwei Beispiele zusammenzubasteln. Dein Code ist schon fast perfekt, nur zwei Sachen habe ich jetzt herausgefunden: die Zeile "app = None" ist überflüssig, und ein Label textet man um mit label.config(text="abcde") Jedenfalls danke für deine Hilfe. Quote
Plenz Posted June 1, 2012 at 08:37 PM Author Posted June 1, 2012 at 08:37 PM Also wenn ich mir das bei Netbeans angucke ist das ziemlich einfach eine GUI zu basteln. Mit Rapid-Q sieht das so aus: DECLARE SUB Geklickt CREATE MYFORM AS QFORM CREATE MyLabel AS QLABEL Caption = "vorher" END CREATE CREATE MyButton AS QBUTTON Caption = "Klick mich!" OnClick = Geklickt END CREATE END CREATE SUB Geklickt MyLabel.Caption = "nachher" END SUB Ist wohl selbsterklärend Quote
AuronX Posted June 1, 2012 at 10:16 PM Posted June 1, 2012 at 10:16 PM die Zeile "app = None" ist überflüssig Oh cool, dann war Python doch besser als ich in Erinnerung hatte hatte befürchtet die Deklaration müsste im Code "vorher" erfolgen. Wegen Rapid-Q: Sieht auf jeden Fall schön simpel aus ^^ Und Offensichtlich werden ja sogar Delegates unterstützt (OnClick = Geklickt) Ich befürchte allerdings, dass es so schnell keine Rapid-Q Bindings geben wird ^^ Zumindest habe ich in diesem Thread das erste Mal davon gehört... Quote
M4ST3R Posted June 1, 2012 at 11:44 PM Posted June 1, 2012 at 11:44 PM Bei Java gibt's einfach einen graphischen Editor ;-) also kein Code von Hand Quote
Plenz Posted June 2, 2012 at 06:36 AM Author Posted June 2, 2012 at 06:36 AM Wegen Rapid-Q: Sieht auf jeden Fall schön simpel aus ^^ Und Offensichtlich werden ja sogar Delegates unterstützt (OnClick = Geklickt) Ich befürchte allerdings, dass es so schnell keine Rapid-Q Bindings geben wird ^^ Zumindest habe ich in diesem Thread das erste Mal davon gehört... Delegates? Nie gehört. Für mich sind das Ereignisse. Rapid-Q-Bindings müssen gar nicht sein, man bräuchte einfach nur eine DLL, die nicht so objektorientiert angesprochen werden muss wie die Tinkerforce.dll. Ich muss allerdings zugeben: auf Callbacks müsste man vermutlich verzichten. Quote
FabianB Posted June 3, 2012 at 09:21 AM Posted June 3, 2012 at 09:21 AM Also wenn ich mir das bei Netbeans angucke ist das ziemlich einfach eine GUI zu basteln. Bei Bedarf mach ich n Video bzw suche eins raus ich hätte großes Interesse an dem Video... Wäre toll, wenn du das machen würdest. Vielleicht kannst du das ja in Kombination mit einem TF-Produkt machen, dann könnten wird das vllt sogar in der Wiki verlinken. Kann ja was ganz einfaches sein. Programm zum Beschreiben des LCDs oder "bei Buttonklick lese Temperatur aus" oder sowas. Quote
M4ST3R Posted June 3, 2012 at 10:02 AM Posted June 3, 2012 at 10:02 AM Ok werde mich morgen Nacht mal dran setzen. Kennt jemand ne gute Software um den Bildschirm Inhalt mitzuschneiden? Hab das noch nie gemacht Quote
FabianB Posted June 3, 2012 at 12:03 PM Posted June 3, 2012 at 12:03 PM Ich benutze immer recordMyDesktop, das gibts aber nur für Linux. Wenn ich mich richtig erinnere, bist du aber Windows-Mensch :-) Hier gibts ne Auswahl mit Bewertungen. Von CamStudio habe ich schon öfters gehört, dass Leute das Benutzen und damit zufrieden sind. http://www.heise.de/download/systemsoftware/bildschirm-recorder-50000505309/ Quote
Imbafestor Posted June 3, 2012 at 12:34 PM Posted June 3, 2012 at 12:34 PM CamStudio ist gut, das hatte ich auch mal verwendet Quote
Plenz Posted June 3, 2012 at 01:58 PM Author Posted June 3, 2012 at 01:58 PM ich hätte großes Interesse an dem Video... Ich hasse Video-Tutorials. Viel besser ist ein geschriebenes Dokument mit Screenshots, das braucht man nicht zu stoppen und weiterlaufen zu lassen, und interessante Zeilen kann man per Copy und Paste gleich weiterbenutzen. Quote
FabianB Posted June 3, 2012 at 01:59 PM Posted June 3, 2012 at 01:59 PM Besser finde ich das auch. Aber das ist in meinen Augen mehr Aufwand, wen ich ihm nicht zumuten möchte, zumal er schon das Video angeboten hat, was mir für diesen Zweck ausreicht. Quote
M4ST3R Posted June 3, 2012 at 02:03 PM Posted June 3, 2012 at 02:03 PM Ihr bekommt beides.:-) ist ja kein großer Aufwand! Ich persönlich mag lieber Videos Quote
FabianB Posted June 3, 2012 at 02:26 PM Posted June 3, 2012 at 02:26 PM Ihr bekommt beides.:-) ist ja kein großer Aufwand! Ich persönlich mag lieber Videos Das nenn ich großzügig ;-) Danke für deine Mühe. Ich bin schon gespannt. Quote
AuronX Posted June 3, 2012 at 05:38 PM Posted June 3, 2012 at 05:38 PM Delegates? Nie gehört. Für mich sind das Ereignisse. Keine Ahnung wie das in Rapid-Q genannt wird, aber es sieht zumindest aus als könnte man über diese Ereignisse Callbacks abbilden. Mehr wollte ich gar nciht sagen ^^ Quote
M4ST3R Posted June 5, 2012 at 12:51 AM Posted June 5, 2012 at 12:51 AM So ich hab mal das versprochene Tutorial fertig gemacht und in einen eigenen Beitrag geschoben. http://www.tinkerunity.org/forum/index.php/topic,587.0.html Das Video mach ich die Tage noch, wenn es noch benötigt wird. Ansonsten Kritik und Wünsche einfach an mich Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.