Hallo Forumfreunde
Ich musste mich in das pyserial 2.2 Modul einarbeiten. Bei dieser Gelegenheit integrierte ich noch trainingshalber Komponenten aus dem Tkinter-GUI-Toolkit für den Aufbau der Benutzeroberfläche und entstand dieses kleine Testprogramm. Ich möchte es hier frei zur Verfügung stellen evt. kann es noch jemand interessierter gebrauchen.
(Be aware i am working with an outcasted GUI-Tool-Kit !)
Ich möchte das pyserial Modul benutzen um digitale Daten für Visualisierungs- und Steuerungszwecke auf ein Mikrokontroller-System zu senden und von dort auch wieder Daten zu empfangen.
Mein Testprogramm sendet ein Telegramm zyklisch aus und empfängt es wieder als Loopback-Signal über die gleiche Schnittstelle. (Pin TX mit RX verbunden) Das Telegramm setzt sich wie folgt zusammen:
a) Präamble-Byte
b) Databyte-1 (Mit Schalterdaten 0...7)
c) Databyte-2 (Mit Schalterdaten 8...15)
d) CRC-16 (Highbyte)
e) CRC-16 (Lowbyte)
Habe das Programm getestet mit:
SuSE 10.0 und 10.3
Windows XP
(Unter Windows kann die Benutzeroberfläche grafisch von der unter Linux abweichen, speziell Objekteigenschaften von Ziehleisten werden vom Windows-Grafik-Manager vorgegeben)
Python 2.4
Meine Entwicklungs-Plattform hier ist:
SuSE 10.0, KWrite, Terminal-Konsole und Python 2.4
Hier der Code:
[Code ausgelagert]
Gruss wuf
Pyserial Tester
Code: Alles auswählen
class ComGui(object):
"""GUI für die Visualisierung der Seriellen Kommunikation"""
def __init__(self,
com_config = [],
ports = [],
callback = None
):
Beispiel:
Code: Alles auswählen
#!/usr/bin/env python
def foo(bar=[]):
bar.append('foo')
print bar
for dummy in xrange(5):
foo()
Code: Alles auswählen
['foo']
['foo', 'foo']
['foo', 'foo', 'foo']
['foo', 'foo', 'foo', 'foo']
['foo', 'foo', 'foo', 'foo', 'foo']
Code: Alles auswählen
def foo(bar=None):
""" @param bar: defaults to []
"""
if not bar:
bar = []
bar.append('foo')
print bar
for dummy in xrange(5):
foo()
Außerdem sieht das hier z.B. unschön aus:
Code: Alles auswählen
self.tx_data_list = [
{
'name' : self.TEXT_PREAMBLE,
'name_label_obj' : None,
'data_label_obj' : None,
'hex_label_obj' : None,
},
{
'name' : self.TEXT_DATA_BYTE1,
'name_label_obj' : None,
'data_label_obj' : None,
'hex_label_obj' : None,
},
{
'name' : self.TEXT_DATA_BYTE2,
'name_label_obj' : None,
'data_label_obj' : None,
'hex_label_obj' : None,
},
{
'name' : self.TEXT_CRC_HIGH,
'name_label_obj' : None,
'data_label_obj' : None,
'hex_label_obj' : None,
},
{
'name' : self.TEXT_CRC_LOW,
'name_label_obj' : None,
'data_label_obj' : None,
'hex_label_obj' : None,
},
]
Auch ist ein knap 900-Zeilen Konstruktur etwas...arg
Müssen nicht, man kann ja auch eine Absicht dahinter unterstellen. Man könnte argumentieren, dass veränderbare Default-Argument als funktionsglobale Closures wirkenaudax hat geschrieben:Default-Argumente müssen Immutables sein, da sie zur Compiletime erstellt werden.
Das klingt etwas abenteuerlich Immutables kann man ja gar nicht verändern, wie kann Veränderung da schlimm seinMan verändert also immer das selbe Objekt, was bei Immutables aber nicht weiter schlimm ist.
Bei unveränderbaren Default-Argumenten kann man das ursprüngliche Objekt ja eben _nicht_ verändern, sondern nur den Namen neu binden.
Naja, eine Konstante, die nur in einer Klasse eine Bedeutung hat, ist imho als Klassenattribut besser platziert.Außerdem kannst du Konstanten auch auf Modul-Ebene ablegen. Sind ja vom semantischen her keine Instanz-Attribute. Evtl. passen sie auch gut auf Klassenebene als statische Variablen, aber dafür ken ich das Program zu wenig :]
Full ack 900 Zeilen sind einfach nur krass, um so mehr, da er das ganze Ding offenbar mit _KWrite_ geschrieben hat Ich bin verdammt beeindruckt, dass er da noch den Durchblick behalten hatAuch ist ein knap 900-Zeilen Konstruktur etwas...arg
Ich würde sogar sagen, dass die Icons und eventuell sogar der ganze GUI Code in einem eigenen Modul wesentlich besser aufgehoben sind. So wie 900 Zeilen für einen Konstruktor krass sind, sind auch 2100 Zeilen etwas krass für ein Modul.
Mit einem vernünftigen setuptools-Skript kann man die Icons eigentlich auch sehr komfortabel als "package data" installieren und über pkg_resources laden. Ich persönlich finde es jedenfalls weder übersichtlich noch elegant, Icons in den Code einzubetten. Imho sollte das Programm schon im Sinne der Les- und Wartbarkeit in mehrere Teilmodule aufgesplittet werden. 2100 Zeilen lese ich nicht "mal eben so"
Hallo audax und lunar.
Danke für eure interressanten Tipps und Anregungen. Die Icons lagere ich normalerweise in ein separates Image-Library-Modul aus. Die einzelnen Klassen können natürlich auch in einzenen Module untergebracht werden. Da hier die Tkinter-Widget mit direkt lesbaren Code Pur im Modul integriert sind braucht es natürlich ein bisschen Platz. Man könnte natürlich für die Widget-Code-Fragmente den ganzen Zeilen-Hub von 80 Zeichen nutzen, dann gebe es im ganzen auch weniger Anzahl Zeilen. Die Lesbarkeit würde aber so negativ beeinträchtigt, dass der Autor nach ein paar Wochen sich selber wundern würde was er da einmal geschrieben hat. Ich möchte den Code auch noch im Altersheim lesen können um Codefragmente davon abstrahieren zu können um zum Beispiel ein Programm für die Pilleneinnahme zu schreiben.
Hier fürs Forum wollte ich das Programm in einem Stück zusammen-schmieden ohne einer Unmenge von Dateien. So, dass ich das Programm nicht in 50 KWrite-Fenstern zusammenlesen muss, was die Übersicht auch nicht gerade steigert.
Bei Tkinter wird halt nicht wie bei einen IDE-Unterstützen Plattform der ganze GUI-Lastige Codemüll in diversen dll's oder Dateien mit verschleiertem Inhalt versteckt.
Noch eine peinliche Frage. Habt ihr das Skript ausprobieren können? Funktioniert es bei euch? Würde mich auch sehr interessieren.
Auf jeden Fall vielen Danke für eure Antworten. Kritik, Verbesserungsvorschläge, Anregungen, Tipps usw. sind jederzeit herzlich willkommen.
Beste Grüsse wuf
Danke für eure interressanten Tipps und Anregungen. Die Icons lagere ich normalerweise in ein separates Image-Library-Modul aus. Die einzelnen Klassen können natürlich auch in einzenen Module untergebracht werden. Da hier die Tkinter-Widget mit direkt lesbaren Code Pur im Modul integriert sind braucht es natürlich ein bisschen Platz. Man könnte natürlich für die Widget-Code-Fragmente den ganzen Zeilen-Hub von 80 Zeichen nutzen, dann gebe es im ganzen auch weniger Anzahl Zeilen. Die Lesbarkeit würde aber so negativ beeinträchtigt, dass der Autor nach ein paar Wochen sich selber wundern würde was er da einmal geschrieben hat. Ich möchte den Code auch noch im Altersheim lesen können um Codefragmente davon abstrahieren zu können um zum Beispiel ein Programm für die Pilleneinnahme zu schreiben.
Hier fürs Forum wollte ich das Programm in einem Stück zusammen-schmieden ohne einer Unmenge von Dateien. So, dass ich das Programm nicht in 50 KWrite-Fenstern zusammenlesen muss, was die Übersicht auch nicht gerade steigert.
Bei Tkinter wird halt nicht wie bei einen IDE-Unterstützen Plattform der ganze GUI-Lastige Codemüll in diversen dll's oder Dateien mit verschleiertem Inhalt versteckt.
Noch eine peinliche Frage. Habt ihr das Skript ausprobieren können? Funktioniert es bei euch? Würde mich auch sehr interessieren.
Auf jeden Fall vielen Danke für eure Antworten. Kritik, Verbesserungsvorschläge, Anregungen, Tipps usw. sind jederzeit herzlich willkommen.
Beste Grüsse wuf
Take it easy Mates!
Im Interesse der Trennung von GUI und Logik sollte man auch bei Tkinter-Programmen GUI und Logik in separate Module packen. Btw, man kann in jedem Toolkit GUI-Code manuell schreiben. Ob das sinnvoll ist, sei mal dahingestellt, ich persönlich nutze lieber WYSIWYG-Designer. GUI-Code zu schreiben ist einfach furchtbar langweilig ...wuf hat geschrieben:Bei Tkinter wird halt nicht wie bei einen IDE-Unterstützen Plattform der ganze GUI-Lastige Codemüll in diversen dll's oder Dateien mit verschleiertem Inhalt versteckt.
2000 Zeilen sind für ein Modul einfach zu lang. Es hätte dem Posting keinen Abbruch getan, dass Ganze auf drei Pastes zu verteilen
Ausprobieren kann ich das nicht ... mein Python hat kein Tk und außerdem wüsste ich nicht, was ich an die serielle Schnittstelle stöpseln sollte
Was hab ich denn anderes gesagt? Ich meinte doch, er sollte die als statische Klassenattribute ablegen...lunar hat geschrieben:Müssen nicht, man kann ja auch eine Absicht dahinter unterstellen. Man könnte argumentieren, dass veränderbare Default-Argument als funktionsglobale Closures wirkenaudax hat geschrieben:Default-Argumente müssen Immutables sein, da sie zur Compiletime erstellt werden.Wäre es Absicht, müsste da wirklich ein ordentlicher Kommentar zu stehen
Tut mir ehrlich leid, dass ich mich dermaßen ungenau ausgedrückt habe...Das klingt etwas abenteuerlich Immutables kann man ja gar nicht verändern, wie kann Veränderung da schlimm seinMan verändert also immer das selbe Objekt, was bei Immutables aber nicht weiter schlimm ist.
Bei unveränderbaren Default-Argumenten kann man das ursprüngliche Objekt ja eben _nicht_ verändern, sondern nur den Namen neu binden.
Ich halte mich zukünftig zurück, wenn ich gerade keine Zeit für Romane hab.Naja, eine Konstante, die nur in einer Klasse eine Bedeutung hat, ist imho als Klassenattribut besser platziert.Außerdem kannst du Konstanten auch auf Modul-Ebene ablegen. Sind ja vom semantischen her keine Instanz-Attribute. Evtl. passen sie auch gut auf Klassenebene als statische Variablen, aber dafür ken ich das Program zu wenig :]
Mein Kommentar war nicht ganz ernst gemeint, wer Default-Argument als Funktions-globale Closures missbraucht, hat imho ein ernsthaftes Problem bei der Strukturierung seines Codes Selbst wenn da ein Kommentar steht ...audax hat geschrieben:Wäre es Absicht, müsste da wirklich ein ordentlicher Kommentar zu stehenlunar hat geschrieben:Müssen nicht, man kann ja auch eine Absicht dahinter unterstellen. Man könnte argumentieren, dass veränderbare Default-Argument als funktionsglobale Closures wirkenaudax hat geschrieben:Default-Argumente müssen Immutables sein, da sie zur Compiletime erstellt werden.
Stimmt, hab dein Posting nicht so genau gelesen... my bad.Was hab ich denn anderes gesagt? Ich meinte doch, er sollte die als statische Klassenattribute ablegen...Naja, eine Konstante, die nur in einer Klasse eine Bedeutung hat, ist imho als Klassenattribut besser platziert.Außerdem kannst du Konstanten auch auf Modul-Ebene ablegen. Sind ja vom semantischen her keine Instanz-Attribute. Evtl. passen sie auch gut auf Klassenebene als statische Variablen, aber dafür ken ich das Program zu wenig :]
Bei mir läuft es, wobei "läuft" heißt, dass man eine aufgeräumte Oberfläche sieht und beim Versuch des Verbindens mit der seriellen Schnittstelle eine ordentliche Fehlermeldung erhält mit nettem Symbol daneben, das das jetzt nicht geklappt hat.wuf hat geschrieben:Noch eine peinliche Frage. Habt ihr das Skript ausprobieren können? Funktioniert es bei euch? Würde mich auch sehr interessieren.
Optisch finde ich es sehr ansprechend gemacht. Ob es dann auch technisch funktioniert kann ich nicht sagen. Ich wüsste leider auch gar nicht, was ich tun sollte, um das zu testen ...
Hallo lunar
Ich finde es merkwürdig, dass bei deiner Python Installation das Tkinter-Package nicht mitinstalliert wurde, da muss sicher etwas schiefgelaufen sein.
Wegen GUI und Logik-Trennung. Könntest du mir bitte einige kurze Tipps bezogen auf mein Skript geben. Natürlich nur wenn du ein paar Minuten freie Zeit verfügbar hast. Ich bin gierig um etwas lernen. Ich möchte meine Programmkünste auf eine höher Ebene bringen ohne mich von Tkinter trennen zu müssen.
OK. Es wird immer jene geben die mit einem schönen Ferrari mit allem drum und dran ohne viel Platz für einen Koffer zu haben herumzufahren und es gibt aber auch immer solche die das lieber in einem Oldtimer (Göppel) mit der Werkzeugkiste und Taschenlampe im Kofferraum tun. Und ein wenig Oel und Fett an den Händen macht doch Spass. Oder?
OK. Vielen Dank für deine Bemühung. Gruss
Ich finde es merkwürdig, dass bei deiner Python Installation das Tkinter-Package nicht mitinstalliert wurde, da muss sicher etwas schiefgelaufen sein.
Wegen GUI und Logik-Trennung. Könntest du mir bitte einige kurze Tipps bezogen auf mein Skript geben. Natürlich nur wenn du ein paar Minuten freie Zeit verfügbar hast. Ich bin gierig um etwas lernen. Ich möchte meine Programmkünste auf eine höher Ebene bringen ohne mich von Tkinter trennen zu müssen.
OK. Es wird immer jene geben die mit einem schönen Ferrari mit allem drum und dran ohne viel Platz für einen Koffer zu haben herumzufahren und es gibt aber auch immer solche die das lieber in einem Oldtimer (Göppel) mit der Werkzeugkiste und Taschenlampe im Kofferraum tun. Und ein wenig Oel und Fett an den Händen macht doch Spass. Oder?
OK. Vielen Dank für deine Bemühung. Gruss
Take it easy Mates!
Nein, dass ist in voller Absicht so geschehen. Gentoo hat einen "tk"-Useflag, den man deaktivieren kann, wenn man – so wie ich – tk nicht braucht.wuf hat geschrieben:Ich finde es merkwürdig, dass bei deiner Python Installation das Tkinter-Package nicht mitinstalliert wurde, da muss sicher etwas schiefgelaufen sein.
Die Icons gehören in ein eigenes Modul, das ist noch nicht mal Code, genau genommen sind das Daten. Un generell alles, was zur GUI gehört. Für eine detaillierte "Analyse" ist mir dein Skript ehrlich gesagt zu lang.Wegen GUI und Logik-Trennung. Könntest du mir bitte einige kurze Tipps bezogen auf mein Skript geben. Natürlich nur wenn du ein paar Minuten freie Zeit verfügbar hast.
Btw, ob du Tkinter nutzt oder nicht, ist mir egal, ich versuche nicht, dir das auszureden Du kannst die Seitenhiebe also lassen
Hallo numerix
First of all. Ich habe das mit dem Menu-Item undShortcut noch nicht abgeschrieben. Wie du siehst wollte ich noch ein anderes Projekt durchziehen.
Wenn du eine Fehlermeldungsanzeige hast funktioniert doch immerhin etwas.
Frageb:
a) Hast du noch eine serielle Schnittstelle auf deinem PC-System? Ich weiss diese Frage ist in der heutigen Zeit ein wenig verrufen. Ich weiss auch nicht ob du mit Mikrokontrollern zu tun hast. Bei den Lowend Kontrollern steht meistens nur eine RS232 als Verbindungsmöglichkeit zu einem PC zur Verfügung.
b) Hast du einen USB-RS232 (seriell) - Konverter? Vermutlich nicht. Braucht es natürlich nur, wenn du entsprechende externe Hardware mit deinem PC, welcher heute nur noch USB-Schnittstellen besitzt, verbinden musst.
c) Hast du einen Notebook der noch ein internes MODEM besitzt? Unter Windows ist diesem MODEM ein internes COM-Port zugeteilt. Bei mir ist das COM-3. Wenn du mein Programm unter Windows startest und als Schnittstelle dieses COM-Port verwendest sollte es die gesendeten Daten über den Loopback automatisch zu meinem Programm zurücksenden. Das heisst die Fehlermeldung auf der GUI sollte
auf 'Die Verbindung ist OK' wechseln.
Wenn eine Verbindung besteht muss eine aktivierte Checkbox auf der TX-Eingabe auf der RX-Ausgabe angezeigt werden. Die Kommunikation wird über die Schaltfläche 'COM-Ein' gestartet. Ist die Verbindung OK, muss das Steckersymbol zusammen gesteckt sein.
Gruss wuf
First of all. Ich habe das mit dem Menu-Item undShortcut noch nicht abgeschrieben. Wie du siehst wollte ich noch ein anderes Projekt durchziehen.
Wenn du eine Fehlermeldungsanzeige hast funktioniert doch immerhin etwas.
Frageb:
a) Hast du noch eine serielle Schnittstelle auf deinem PC-System? Ich weiss diese Frage ist in der heutigen Zeit ein wenig verrufen. Ich weiss auch nicht ob du mit Mikrokontrollern zu tun hast. Bei den Lowend Kontrollern steht meistens nur eine RS232 als Verbindungsmöglichkeit zu einem PC zur Verfügung.
b) Hast du einen USB-RS232 (seriell) - Konverter? Vermutlich nicht. Braucht es natürlich nur, wenn du entsprechende externe Hardware mit deinem PC, welcher heute nur noch USB-Schnittstellen besitzt, verbinden musst.
c) Hast du einen Notebook der noch ein internes MODEM besitzt? Unter Windows ist diesem MODEM ein internes COM-Port zugeteilt. Bei mir ist das COM-3. Wenn du mein Programm unter Windows startest und als Schnittstelle dieses COM-Port verwendest sollte es die gesendeten Daten über den Loopback automatisch zu meinem Programm zurücksenden. Das heisst die Fehlermeldung auf der GUI sollte
auf 'Die Verbindung ist OK' wechseln.
Wenn eine Verbindung besteht muss eine aktivierte Checkbox auf der TX-Eingabe auf der RX-Ausgabe angezeigt werden. Die Kommunikation wird über die Schaltfläche 'COM-Ein' gestartet. Ist die Verbindung OK, muss das Steckersymbol zusammen gesteckt sein.
Gruss wuf
Take it easy Mates!
Hallo lunar
Ich wollte dich nicht verletzen und entschuldige mich dafür, wenn du mein Post als Seitenhieb aufgefasst hast.
Es ist mir auch klar das base64-codierte Icons kein Code ist sondern Daten. Wenn man es so akribisch genau nimmte ist ein Python-Skript auch kein Code sondern sondern nur simple Daten.
Danke für deine Antwort Gruss wuf
Ich wollte dich nicht verletzen und entschuldige mich dafür, wenn du mein Post als Seitenhieb aufgefasst hast.
Es ist mir auch klar das base64-codierte Icons kein Code ist sondern Daten. Wenn man es so akribisch genau nimmte ist ein Python-Skript auch kein Code sondern sondern nur simple Daten.
Danke für deine Antwort Gruss wuf
Take it easy Mates!
So war das nicht gemeint, ich fühle mich nicht "verletzt" Ich hatte nur das Gefühl, dass du seit unserem Disput über Tk immer glaubst, ich wolle dir Tk ausreden Ich wollte klarstellen, dass dem nicht so ist, weil ich das Gefühl hatte, dass _du_ dich verletzt fühlstwuf hat geschrieben:Ich wollte dich nicht verletzen und entschuldige mich dafür, wenn du mein Post als Seitenhieb aufgefasst hast.
Ich würde mal sagen, wir haben uns kolossal missverstanden
Hallo Forumfreunde
Habe den Pyserial-Tester noch unter SuSE 10.0 mit Python 2.5 ausgetestet und stellte fest, dass Tkinter betreffs grafischem Verhalten näher an Windows gebracht wurde, dies betrifft hauptsächlich das CheckBox-Widget. Ich passte den Pyserial-Tester hierfür an. Gleichzeitig stellte ich fest, dass nach dem aktivieren der Schaltfäche 'TX-Löschen' ein Problem besteht. Habe auch noch diesen Fehler behoben.
Hier die neue Version pyserial_tester_01_02_02.py:
[Code ausgelagert]
Gruss wuf
Habe den Pyserial-Tester noch unter SuSE 10.0 mit Python 2.5 ausgetestet und stellte fest, dass Tkinter betreffs grafischem Verhalten näher an Windows gebracht wurde, dies betrifft hauptsächlich das CheckBox-Widget. Ich passte den Pyserial-Tester hierfür an. Gleichzeitig stellte ich fest, dass nach dem aktivieren der Schaltfäche 'TX-Löschen' ein Problem besteht. Habe auch noch diesen Fehler behoben.
Hier die neue Version pyserial_tester_01_02_02.py:
[Code ausgelagert]
Gruss wuf
Take it easy Mates!
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Ich habe ebenso das Paket python-tk nicht installiert, da ich es nicht brauche und es auch keine Programme gibt die ich nutzte, die das nutzen würden - daher ist es auch nicht vorhanden. Das ist auch sehr nützlich auf Serversystemen, da python-tk im Endeffekt die ganzen Xlibs mitzieht, die man auf solchen Systemen nicht braucht und die Unnötig Kapazität verschwenden.lunar hat geschrieben:Nein, dass ist in voller Absicht so geschehen. Gentoo hat einen "tk"-Useflag, den man deaktivieren kann, wenn man – so wie ich – tk nicht braucht.wuf hat geschrieben:Ich finde es merkwürdig, dass bei deiner Python Installation das Tkinter-Package nicht mitinstalliert wurde, da muss sicher etwas schiefgelaufen sein.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice