Re: Simple webserver
Il 19/10/2023 00:09, Janis Papanagnou ha scritto: I am pondering about writing a client/server software with websockets as communication protocol. The clients will run in browser as Javascript programs and the server may be in any (any sensible) programming language running standalone to be connected remotely by the browser-based JS clients. I found a Python sample[*] but I am neither familiar with Python nor with the 'simple_websocket_server' package that is used in that sample code. But the code looks so simple that I'm considering to learn and use Python for the task. The requirements I have are quite simple; I want to get the client "address"/identifier from an incoming message, store it in a list, and send responses to all active clients for which addresses have been stored. Can anyone tell me whether a simple extension of that "echo incoming message" sample[*] would be easily possible with Python and with that 'simple_websocket_server' package used? Thanks for any hints (or search keywords, or code samples)! Janis [*] https://pypi.org/project/simple-websocket-server/ I'm not sure, but MQTT protocol could help for this application. -- https://mail.python.org/mailman/listinfo/python-list
Multithreading? How?
I need to develop a Python application that is a sort of gateway between to networks: a "serial bus" network (think of a serial port or a USB connection) and a MQTT connection (in my case, it's AWS IoT service). On the bus, a proprietary protocol is implemented. From the bus, the app knows the status of the system (think of a simple ON/OFF status). The user can retrieve the status of the system through MQTT: it sends a message to read/status MQTT topic and receive back a message with the current status on read/status/reply MQTT topic. Of course, they are just examples. On the contrary, when the app detects a status change reported from the serial bus (think of a transition from ON to OFF), it sends a MQTT message. I'm thinking to split the application in three classes: Bus, App and IoT. Bus and IoT are also threads. The thread of Bus manages the serial protocol, while the thread of IoT manages MQTT connection with the broker (the server). However I don't know if it could be a good architecture. Suppone Bus thread receives a new status from the system. In the context of ThreadBus, the object Bus could call a method of App object: app.set_status(new_status_from_the_bus) In the App I have: class App(): .. def set_status(new_status): # Could be called from ThreadBus if new_status != self.new_status: self.new_status = new_status # Do some actions on status change def get_status():# Could be called from ThreadIoT return self.status Of course, IoT object needs to know the current status of the system when a message is received from MQTT. So ThreadIoT could call app.get_status(). I think this architecture has some problems with race conditions or threads synchronization. What happens if IoT calls get_status() exactly when set_status() called by ThreadBus is executing? If status is a big data structure, set_status() could be interrupted by get_status() that could get a completely corrupted status, because it was only partly updated by set_status(). I know I can use locks or semaphores in get_status() and set_status(), but I don't know if this is a good approach. Consider that the system is complex, it isn't composed by a simple single status. It has many many parameters that are collected from the serial bus. Should I use a lock for every [get|set]_status(), [get|set]_dimensions(), [get|set]_battery_level(), [get|set]_mains_present(), and so on? Another possibility is to use a Queue for Bus and a Queue for IoT. So the set_status(new_status) called from Bus object will be transformed in a put in the queue: app_queue.put({"type": "new_status", "data": ...}) However how could be transformed the get_status() from IoT? How the return value (the current status) is real retrieved? class IoT(): .. def status_request_from_MQTT(): app_queue.put({"type": "get_status"}) # How to get the status to return? return current_status Should the app put the status on the same queue and should IoT waits for a new message in the Queue? def status_request_from_MQTT(): app_queue.put({"type": "get_status"}) try: current_status = app_queue.get(timeout=10) except Empty: # What to do? return current_status Again another approach is to avoid multi-threading at all and create a single "main loop" function that waits at the same time for incoming events on the serial bus and MQTT (how?). I don't know if this could be done in my case, because I'm using awscrt Python module and it works through callbacks that I think is called from another thread. Any suggestions on this architecture? -- https://mail.python.org/mailman/listinfo/python-list
Re: Python threading and sharing variables
Il 05/07/2017 09:56, pozz ha scritto: > [...] It seems it works, but I'm not sure it is the correct way to share the variable self.cnt. It is only written in the long thread and only read in the main thread. Could a single Python instruction be interrupted (in this case, self.cnt = i)? Should I use a locking mechanism when reading/writing? What about if the variable is more complex, for example a list or dictionary? Even in this case, is it safe to avoid locking on a shared variable if the operation on the variable is performed in a single Python instruction? Ok, maybe this atomic behaviour depends on the Python implementation, so it's better to avoid relying on atomicity and use a lock to access shared variables from different running thread. However in my simple case one thread writes the variable and the other reads it. In this case is it safe to avoid locks? -- https://mail.python.org/mailman/listinfo/python-list
Python threading and sharing variables
I'd like to launch *and control* a long thread. I want to print the progress of the long thread in the main thread. It's a GUI script, here it's a console script only to simplify. import threading import time class MyClass: def start(self): self.max = 5 self.pause = 1 t = threading.Thread(target=self.thread) t.start() i = -1 while self.cnt != self.max - 1: if i != self.cnt: print("{:d}".format(self.cnt)) i = self.cnt print("Finished") def thread(self): for i in range(self.max): self.cnt = i time.sleep(self.pause) c = MyClass() c.start() It seems it works, but I'm not sure it is the correct way to share the variable self.cnt. It is only written in the long thread and only read in the main thread. Could a single Python instruction be interrupted (in this case, self.cnt = i)? Should I use a locking mechanism when reading/writing? What about if the variable is more complex, for example a list or dictionary? Even in this case, is it safe to avoid locking on a shared variable if the operation on the variable is performed in a single Python instruction? -- https://mail.python.org/mailman/listinfo/python-list
Re: [gettext] How to change language at run-time
Il 15/06/2017 15:22, Peter Otten ha scritto: pozz wrote: I know I can load multiple gettext.translation: it = gettext.translation('test', localedir="locale", languages=["it"]) es = gettext.translation('test', localedir="locale", languages=["es"]) and install one translation at run-time when I want at a later time (when the user selects a new language): it.install() or es.install() However the problem is that strings already translated are not translated again when a new translation is installed. So they stay at the language selected during start-up and don't change after a new install(). One solution is to restart the application, but I think there's a better and more elegant solution. You need a way to defer the translation until the string is actually used. The documentation has a few ideas https://docs.python.org/dev/library/gettext.html#deferred-translations and here's another one -- perform the translation in the __str__ method of a custom class: > [...] It's a nice trick. However you will have a string that isn't a string, but a class. I think you can't use the class everywhere you can use a string. For example, len() can't be called. -- https://mail.python.org/mailman/listinfo/python-list
[gettext] How to change language at run-time
I know I can load multiple gettext.translation: it = gettext.translation('test', localedir="locale", languages=["it"]) es = gettext.translation('test', localedir="locale", languages=["es"]) and install one translation at run-time when I want at a later time (when the user selects a new language): it.install() or es.install() However the problem is that strings already translated are not translated again when a new translation is installed. So they stay at the language selected during start-up and don't change after a new install(). One solution is to restart the application, but I think there's a better and more elegant solution. -- https://mail.python.org/mailman/listinfo/python-list
Re: How to use two threads (GUI and backend)
Il 27/10/2016 13:33, jmp ha scritto: On 10/27/2016 12:22 PM, pozz wrote: Anyway I don't like this approach, because the main (and single) thread should check in_waiting every X milliseconds. If X is too high, I could wait for the answer even if it is already ready in the input buffer. If X is too low, the application consumes a lot of clocks to check in_waiting. I would prefer to have a callback automatically called when the read operation is complete. And I think the only method is using another (blocking) thread. The blocking function read returns *immediately* when all the bytes are received. And I think during blocking time, the thread isn't consuming CPU clocks. Threads do consume CPU clocks. An operation within a thread will not consume less CPU clocks, however, the scheduler will interrupt the thread and give other threads/operations a chance to process as well. Threads implement paralellism, not performances. Yes of course, but when the backend thread calls the *blocking* function pyserial.read(), it *doesn't* consume CPU clocks (at least, I hope). The low-level implementation of pyserial.read() should move the thread in a "suspend" or "waiting" state, so the thread scheduler shouldn't activate it. The suspend state is exited (automatically from OS, I think) when one or more bytes are ready in the input buffer. From what I understand of your context, you don't want you GUI to "freeze" when waiting for the remote application. That's a valid concern. You can use threads to fix that(or you can use already written working python libraries that would mask this low level programing, it's up to you). What you should not do is focus on gaining "CPU clocks". You just don't care. It's probably not an issue. If it is, drop python and implement your app in C. Because I don't want to drop python, I want to learn the best tecnique to use to have the best performance. -- https://mail.python.org/mailman/listinfo/python-list
Re: How to use two threads (GUI and backend)
Il 26/10/2016 16:18, jmp ha scritto: On 10/26/2016 02:45 PM, pozz wrote: Il 26/10/2016 13:16, jmp ha scritto: [...] I suggest you write a GUI that make synchronouscalls to a remote application, if possible. If the remote app is in python, you have access to remote protocols already written for you, Pyro is one of them, you can skip the low level communication part. I'm not sure Pyro (or similar alternatives) helps in my case. The real problem is that retrieving status from remote device is a slow operation. If the GUI thread blocks waiting for the answer, the GUI blocks and the user complains. From Pyro documentation: --- Normal method calls always block until the response is returned. This can be any normal return value, None, or an error in the form of a raised exception. The client code execution is suspended until the method call has finished and produced its result. --- So, even with Pyro, I need to have another thread that manages Pyro communication (instead of serial communication)... additional problems. Also from the Pyro doc: You can execute a remote method call and tell Pyro: “hey, I don’t need the results right now. Go ahead and compute them, I’ll come back later once I need them”. The call will be processed in the background and you can collect the results at a later time. [...] It is possible to define one or more callables (the “call chain”) that should be invoked automatically by Pyro as soon as the result value becomes available. I already read that, it is the feature "Asynchronous ('future') remote calls & call chains". This approach can be taken also without pyro at all, just using pyserial module (and I think all the communication libraries). With pyserial, I can set a read timeout value of zero: timeout = 0: non-blocking mode, return immediately in any case, returning zero or more, up to the requested number of bytes In this way, I can implement exactly the same mechanism of pyro in asyncronous mode. With pyserial I could avoid setting timeout=0, using in_waiting property ("number of bytes in the input buffer"). Anyway I don't like this approach, because the main (and single) thread should check in_waiting every X milliseconds. If X is too high, I could wait for the answer even if it is already ready in the input buffer. If X is too low, the application consumes a lot of clocks to check in_waiting. I would prefer to have a callback automatically called when the read operation is complete. And I think the only method is using another (blocking) thread. The blocking function read returns *immediately* when all the bytes are received. And I think during blocking time, the thread isn't consuming CPU clocks. I could try with asyncio feature of pyserial, but it is classified as "experimental". -- https://mail.python.org/mailman/listinfo/python-list
Re: How to use two threads (GUI and backend)
Il 26/10/2016 13:16, jmp ha scritto: [...] I suggest you write a GUI that make synchronouscalls to a remote application, if possible. If the remote app is in python, you have access to remote protocols already written for you, Pyro is one of them, you can skip the low level communication part. I'm not sure Pyro (or similar alternatives) helps in my case. The real problem is that retrieving status from remote device is a slow operation. If the GUI thread blocks waiting for the answer, the GUI blocks and the user complains. From Pyro documentation: --- Normal method calls always block until the response is returned. This can be any normal return value, None, or an error in the form of a raised exception. The client code execution is suspended until the method call has finished and produced its result. --- So, even with Pyro, I need to have another thread that manages Pyro communication (instead of serial communication)... additional problems. -- https://mail.python.org/mailman/listinfo/python-list
Re: How to use two threads (GUI and backend)
Il 26/10/2016 13:27, Antoon Pardon ha scritto: Op 26-10-16 om 12:22 schreef pozz: Il 26/10/2016 09:13, pozz ha scritto: [...] When the user press Start button (the pressed handler is in the GUI class): self.comm_active = True threading.Thread(target=self.comm_thread).start() The backend thread is: def comm_thread(self): while self.comm_active: self.device.get_status() GLib.idle_add(self.polling_received) time.sleep(1) self.m.close() [...] Now I have some concerns even in using self.comm_active. It is a boolean variable accessed by the GUI thread (inside Start/Stop buttons handler) and backend thread (in the "while self.comm_active" instruction). Is it safe to access this variable from two different threads? Should I implement a safer and more complex mechanism? If yes, what mechanism? Accessing from multiple thread shouldn't be a problem. As long as you only change it in one thread. I don't want to doubt what you have written, but... are you definitevely sure? I tried to search for some authoritative documentation about this topic, but I couldn't find any. I have many years of experiece in embedded firmware written in C for small microcontrollers, so I know the problems that could occur when a variable is read in one ISR (interrupt service routine) and written in the main loop (or viceversa). ISR and main loop can be considered two threads. If the variable is 32-bits and the microcontroller can't write atomically (without any interruption) a 32-bit variable, bad things could occur. If the main loop is updating the variable from 0x01020304 to 0xA1A2A3A4 and the change happens on a byte basis, the ISR could access a completely wrong value, for example 0x0102A3A4. So the main question here is: does python *specification/standard* guarantees atomic operations? If yes, what are they? -- https://mail.python.org/mailman/listinfo/python-list
Re: How to use two threads (GUI and backend)
Il 26/10/2016 09:13, pozz ha scritto: > [...] When the user press Start button (the pressed handler is in the GUI class): self.comm_active = True threading.Thread(target=self.comm_thread).start() The backend thread is: def comm_thread(self): while self.comm_active: self.device.get_status() GLib.idle_add(self.polling_received) time.sleep(1) self.m.close() > [...] Now I have some concerns even in using self.comm_active. It is a boolean variable accessed by the GUI thread (inside Start/Stop buttons handler) and backend thread (in the "while self.comm_active" instruction). Is it safe to access this variable from two different threads? Should I implement a safer and more complex mechanism? If yes, what mechanism? -- https://mail.python.org/mailman/listinfo/python-list
Re: How to use two threads (GUI and backend)
Il 26/10/2016 09:13, pozz ha scritto: > [...] What is the best approach to use in my scenario (GUI and backend communication)? I just found this[1] page, where the thread approach is explained with the following code: --- import threading import time from gi.repository import GLib, Gtk, GObject def app_main(): win = Gtk.Window(default_height=50, default_width=300) win.connect("delete-event", Gtk.main_quit) progress = Gtk.ProgressBar(show_text=True) win.add(progress) def update_progess(i): progress.pulse() progress.set_text(str(i)) return False def example_target(): for i in range(50): GLib.idle_add(update_progess, i) time.sleep(0.2) win.show_all() thread = threading.Thread(target=example_target) thread.daemon = True thread.start() if __name__ == "__main__": # Calling GObject.threads_init() is not needed for PyGObject 3.10.2+ GObject.threads_init() app_main() --- This is similar to my approach, with a main difference: the callback update_progress() added to the GLib idle loop (so executed in the main GUI thread) receives all the data as arguments (the value i to write as text in the progress widget). In my case, I have many many properties of the remote device. So my first idea is to get directly the value by accessing variables changed during backend thread... I think this is wrong. [1] https://wiki.gnome.org/Projects/PyGObject/Threading -- https://mail.python.org/mailman/listinfo/python-list
How to use two threads (GUI and backend)
I'm designing a GUI application in Python (with pyGObject, so GTK). The application communicates with a remote device (connected through RS232, but it could be on Internet) to retrieve its status and set/get its configuration. When the user press "Start" button, the application starts sending "GET STATUS" requests to the remote device, waiting its response. When the response arrives, the GUI widgets are refreshed with the new status. The "GET STATUS" requests are send at a regular frequency (polling mode). I thought two split the application in two threads: the GUI main thread that manages graphical widgets and user interaction; the backend thread that manages low-level communication. When the user press Start button (the pressed handler is in the GUI class): self.comm_active = True threading.Thread(target=self.comm_thread).start() The backend thread is: def comm_thread(self): while self.comm_active: self.device.get_status() GLib.idle_add(self.polling_received) time.sleep(1) self.m.close() self.device.get_status() is blocking. It is executed in backend thread, so the GUI isn't blocked. self.polling_received() function will be executed in main thread (thanks to GLib.idle_add), because it will change widgets properties. Now the get_stats() of self.comm object: def get_status(self): self.property1 = self.property2 = return And self.polling_received() of GUI class: def polling_received(self): txtEntry1.set_text(self.comm.property1) txtEntry2.set_text(self.comm.property2) I didn't fully tested this, but it seems it works well. However I have some concerns, mainly for thread syncronizations. self.polling_received() is executed in GUI thread and reads properties (self.comm.property1, ...) that are changed during parsing of responses in self.comm.get_status() function that is executed in the backend thread. So the two threads use the same variables/objects without synchronization. Is this a problem? What is the best approach to use in my scenario (GUI and backend communication)? -- https://mail.python.org/mailman/listinfo/python-list
Converting the keys of a dictionary from numeric to string
I have a dictionary where the keys are numbers: mydict = { 1: 1000, 2: 1500, 3: 100 } I would like to convert keys from number to string representation: mydict = { "apples": 1000, "nuts": 1500, "tables": 100 } Of course, somewhere I have the association between key-numbers and key-strings, maybe in another dictionary: keydict = { 1: "apples", 2: "nuts", 3; "tables" } How could I make the conversion? My solution: keydict = { 1: "Joseph", 2: "Michael", 3: "John" } mydict = { 1: 1000, 2: 2000, 3: 3000 } newdict = {} for k in mydict.keys(): newdict.update({keydict[k]: mydict[k]}) print(newdict) I tried changing just mydict (without creating newdict), without success. -- https://mail.python.org/mailman/listinfo/python-list
Re: [FAQ] "Best" GUI toolkit for python
Il 18/10/2016 18:41, Demosthenes Koptsis ha scritto: > My favorite GUIs are PyQt and wxPython. > > I prefer PyQt than PySide because PySide seem to me like an abandoned > project. > > Also i prefer PyQt than wxPython because i can design the forms in > QtDesigner easily. > > wxPython and wxWidgets do not have a GUI designer competitor to QtDesigner. > > So, my choice is PyQt ! Have you compared pyQt with pyGObject (GTK)? -- https://mail.python.org/mailman/listinfo/python-list
Re: [FAQ] "Best" GUI toolkit for python
Il 18/10/2016 16:56, Michael Torrie ha scritto: On 10/18/2016 02:33 AM, Mark Summerfield wrote: When I started out I used Qt Designer to produce .ui files (XML) and then used the Qt uic tool to convert this to C++ (although you can convert to Python using pyuic). I then studied the code and learnt from that. And it turns out that it isn't very hard. There is QVBoxLayout - widgets one above the other; QHBoxLayout; widgets side by side; QGridLayout - widgets in a grid. The only complication is when you nest these, say a QVBoxLayout inside a QHBoxLayout inside a QGridLayout; but in practice, once you've done it a few times it isn't hard to picture. However, I know highly skilled people who prefer to use Qt Designer, so it is no big deal either way. I am certainly not highly skilled. But I definitely do use the Designer for everything related to the GUI. I don't, however, use uic or pyuic. What I recommend these days is to use the xml .ui file directly in your program to create the objects for you. In C++ with an EXE, you can incorporate the .ui file into the executable as a resource. In Python, I would just bundle it with all the other resources I might be using. For custom widgets I either build a simple plugin for Designer that lets me use the widgets as any other in the visual layout. Alternatively, I'll just change the class type in properties. The way you use the .ui file loader is to create a class in Python, usually for each window or dialog, and subclass it from the appropriate Qt type such as QDialog. Then in the __init__() method, you call PyQt.uic.loadUi and it brings all the widgets in and initializes them and adds them to the QDialog you are defining. And if you follow the naming scheme for your callbacks of on_widgetname_signalName(), it will auto connect them. For example, if my button was called "myButton", I could name a slot to be on_myButton_clicked() and it would connect automatically. PySides allows something similar with QUiLoader. I use a wrapper class that Sebastion Wiesner wrote to make it closer to a one-liner wrapper function like PyQt offers. What are the differences between PySides and PyQt... apart the licence? Is PySides usable as PyQt? I agree with you about making GUIs programmatically being not hard, especially when one is learning. When I first started using Qt, coming from GTK, I had to get used to a similar but different boxing model. In GTK, when packing widgets you specify both the expansion and spacing while packing. In Qt, you have explicit spacers to insert into the boxes. I'm not sure which method is better. So you have some experience on GTK and QT. Could you spend some time to describe a few differences? What do you like with Gtk and what you don't? And for Qt? When you worked with Gtk, have you used Glade as GUI Builder? Could you compare Glade and QT Designer? -- https://mail.python.org/mailman/listinfo/python-list
Re: [FAQ] "Best" GUI toolkit for python
Il 18/10/2016 09:42, Mark Summerfield ha scritto: PySide/PyQt On Windows I use Python 3.4 + PySide 1.2.4 (Qt 4.8). I have found this very reliable and use it for both my personal projects and for my commercial products. I don't use a GUI design tool but you could use Qt Designer to visually draw your GUI since PySide can read the .ui files it outputs. Eventually PySide 2 will be available, and that will support Qt 5 (for what that's worth) and presumably Python 3.5+ (which I look forward to). Why don't you use a GUI design tool? Better... how can you design a GUI without seeing it? For me it's very difficult to "code the GUI". Gtk/PyGObject/PyGI Windows is in no way a first class platform for this, so I wouldn't use it. (I wouldn't use it on any other platform either: I think the introspection idea is excellent and wish Qt had done it; but I personally really dislike the direction Gtk has gone in recent years.) Could you explain those... "directions" that you don't like? Tkinter This is okay for many simple use cases. However, creating custom widgets in Tkinter is non-trivial to say the least (especially compared with say,PySide or wxPython), and there is no support for _editable_ styled text. (If someone can prove me wrong I'd be glad to know how to edit text in Tkinter and toggle bold, italic, underline, super- and sub-script, font family, font size, and color. I can do most of these - but not all, and haven't seen any other code that can do them all either. Note that I'm not talking here about syntax highlighting but rather word-processor-style styling.) wxPython I've heard some people say they use Python 3 + Phoenix successfully. On the plus side it uses the native widgets so has a native look and feel. But what I find frustrating is that there are many widgets with overlapping functionality so it isn't clear which one is the best to use. For Windows specifically, you could use https://pythonnet.github.io/ This gives you access to the CLR so you should be able to use a lot of stuff you're familiar with from VB; some of which might even work on Linux with the Mono runtime. A completely different cross-platform approach is to use a web browser as the GUI toolkit. For example: https://github.com/r0x0r/pywebview + https://github.com/dddomodossola/remi or https://flexx.readthedocs.io/en/stable/ There are other toolkits too, e.g., http://pybee.org/project/projects/libraries/toga/ (but this has very little documentation) Or https://kivy.org/#home And there are more (e.g., libui, IUP, SDL2). Good luck! -- https://mail.python.org/mailman/listinfo/python-list
Re: [FAQ] "Best" GUI toolkit for python
Il 18/10/2016 03:25, Paul Rubin ha scritto: If you're just getting started and you're not trying to make something super slick, I'd suggest Tkinter. It's easy to learn and use, you can bang stuff together with it pretty fast, it's included with various Python distributions so you avoid download/installation hassles, and it's pretty portable across various desktop OS's (not mobile for some reason). Is there a visual GUI builder for Tkinter? What I like about gtk/glade is a good separation between the code of graphical elements and the code of funcionality/behaviour (somewhat similar to CSS). The widgets are designed and customized with Glade application that generates a xml (.glade) file that can be supplied directly to the python script. In theory, it is very clean and simple. So I'd like to have a visual GUI builder. I have many problems to imagine the GUI in my mind when writing code. The downside is that you get industrial-looking UI's that implement typical GUI functionality but don't have ultra precise control or carefully crafted widgets like some of the other toolkits do. Could you explain better what do you mean with "industrial-looking UI"? What can I do and what *can't* I do with Tkinter? Kivy (kivy.org) also seems worth looking at if you're trying to be cross-platform. It runs on both desktop and mobile. It seems nice. Does it use the native look on Windows? Although, one of my mobile-using buddies tells me that mobile apps are now passé and these days people just write web apps for mobile. I'm not sure this sentence is correct. *Big* services (mainly social, facebook, linkedin, ...) have a custom mobile app for Android and iOS. They also have a website (I can check my Facebook profile through a simple web browser or through the related app), but they insist to install an app. -- https://mail.python.org/mailman/listinfo/python-list
Re: [FAQ] "Best" GUI toolkit for python
Il 18/10/2016 02:57, Wildman ha scritto: On Tue, 18 Oct 2016 00:58:42 +0200, pozz wrote: I'm sorry, I know it is a FAQ..., but I couldn't find a good answer. I'm learning python and I'd like to start creating GUI applications, mainly for Windows OS. In the past, I wrote many applications in Visual Basic 4: it was very fast and you could create simple but effective GUIs in Windows in some minutes. I am also learning Python so my experience is limited. I have tried pyGTK and Tkinter. GTK's concept of the hbox and vbox gave me of difficulty. I couldn't get the GUI to look the way I wanted. Yes, it's exactly my situation. I understand boxes give a lot of flexibility, but for simple GUI they are very complex. Did you try Glade GUI builder applcation? OTOH, Tkinter offers a way to place widgets on a window/frame in a precise way: self.widget.place(x=#, y=#) That is similar to VB's move statement. GTK may have such a feature but I was not able to find it. Yes, it seems GTK has a similar feature. It is the container GtkFixed (https://developer.gnome.org/gtk3/stable/GtkFixed.html). The GtkFixed widget is a container which can place child widgets at fixed positions and with fixed sizes, given in pixels. GtkFixed performs no automatic layout management. At the moment, I didn't tested GtkFixed yet, but it seems very simple to use. I hope Glade gives a good support for it. Anyway, my choice based on my limited experience is Tkinter. Here is a good place to start... http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/index.html This will give you several places to look for additional info... https://duckduckgo.com/?q=tkinter+tutorials=h_=web Ok, thank you. -- https://mail.python.org/mailman/listinfo/python-list
[FAQ] "Best" GUI toolkit for python
I'm sorry, I know it is a FAQ..., but I couldn't find a good answer. I'm learning python and I'd like to start creating GUI applications, mainly for Windows OS. In the past, I wrote many applications in Visual Basic 4: it was very fast and you could create simple but effective GUIs in Windows in some minutes. Actually I'm not interested in cross-platform application, however it could be a good feature to have. I understand there are some alternatives, with pros and cons: - Tkinter - GTK (pyGObject for Python3) - QT (pyQt or pySide for LGPL licence) - wxPython (wxPython/Phoenix for Python3) - FLTK There is an entire page on python website that talks about GUI toolkits: https://wiki.python.org/moin/GuiProgramming I can't test all of them to understand what is the best for my needs. I started with GTK some weeks ago and I encountered many troubles: - pyGtk is old, better to use pyGObject (it isn't so clear at first) - Glade Windows binaries on website are old, better to use the binary that can be downloaded from Msys2 project I'm not sure, but I don't like too much this solution... maybe it's only a matter of time. Glade application (for visual GUI building) seems not very stable under Windows. I had many crashes. Moreover it's very complex to understand the arrangement of widgets on a window. Even a simple listbox is implemented through the GtkTreeView widget that is... very complex to understand. Documentation isn't so good: it's so simple to put a note on the Windows binaries page of glade to download a more recent version through Msys2! So I'm thinking to evaluate other solutions. wxWidgets is attractive for it's native look, but python implementation Phoenix for Python3 is in alpha stage. Moreover wxGlade (the GUI builder application) needs Python2, but I couldn't understand if the generated code is compatible with wxPython/Phoenix. QT is another alternative, but I need pySide for LGPL support (pyQt isn't LGPL). Is it good as pyQt project? Any suggestions? One of my requirement is to have a good documentation/support from community... and the solution must be currently active. -- https://mail.python.org/mailman/listinfo/python-list
Without compilation, how to find bugs?
I come from the C language, that is a compiled and strongly typed language. I learned many good tricks to write good code in C: choose a coding style, turn on as many warnings as possible, explicitly declare static variables and functions (when needed), explicitly declare const variables (if the piece of code will not change them), explicitly declare all the functions, and so on. All the tricks have a common goal: to discover bugs as soon as possible, mostly during compilation process. Indeed I usually find some bugs during compilation (or static analysis). It seems to me very important. Now I'm learning Python and it appears to me very simple, but at the same time highly dangerous. For example, I can write a function that accepts two arguments and call it with only one argument. I can execute the script without any problem and I will not notice the bug until I test exactly the erroneous line of code (the call with only one argument). However, I think the language interpreter could emit the error before launching the script even without executing the wrong instruction, because it perfectly knows how many arguments the function wants and that one instruction calls it with a wrong number of arguments. Are the things exactly how I understood, or do I miss something in Python? -- https://mail.python.org/mailman/listinfo/python-list
pyserial and threads
I'm trying to create a simple program in Python that opens N serial ports (through pyserial) and forward every byte received on one of those ports to the other ports. At startup I open the ports and create and start a thread to manage the receiving. When a byte is received, I call the .write() method for all the other ports. It works, but sometimes it seems to block. I think I haven't used correctly the threads. Below is my code, I hope someone can help me. Consider that I'm a newbie in python and I never used threads before. import serial import threading import sys, os import signal import time class Miniterm(object): def __init__(self, port, baudrate): self.serial = serial.Serial(port, baudrate, timeout=1) def start(self, com_list): self.alive = True self.com_list = com_list self._reader_alive = True self.receiver_thread = threading.Thread(target=self.reader) self.receiver_thread.setDaemon(True) self.receiver_thread.start() def stop(self): self.alive = False def reader(self): try: while self.alive and self._reader_alive: data = self.serial.read(1) if len(data) > 0: for p in self.com_list: if p[1] != self: p[1].write(data) except serial.SerialException: self.alive = False raise def write(self, data): self.serial.write(data) if __name__ == "__main__": ports = [] for com in sys.argv[1:]: try: miniterm = Miniterm(com, 38400) except serial.SerialException: sys.stderr.write("could not open port " + com) sys.exit(1) ports.append((com, miniterm)) for p in ports: p[1].start(ports) print("Port " + p[0] + " has started", flush=True) while True: time.sleep(1) -- https://mail.python.org/mailman/listinfo/python-list
Re: pyserial and threads
Il 17/09/2015 15:04, Dennis Lee Bieber ha scritto: On Thu, 17 Sep 2015 12:00:08 + (UTC), alisterdeclaimed the following: I can see the data being transmitted snowballing & running away in a +ve feedback loop very easily. Especially if a few of the remote devices are configured to ECHO data... No ECHO. Main thing I'd probably change is... Since the COM port identification is already being provided during initialization of the handler object, why maintain a list of (com, handler) pairs, and the subsequent subscripting -- just save the com port as an attribute of the object. One could also make a copy of the object list in the start method, and at that point, scan the list and remove that one's own identity. That would remove the need for always testing "is the object I'm about to send to really me?" Ok, they are optimizations, but I don't think they solve my issue. -- https://mail.python.org/mailman/listinfo/python-list
Re: pyserial and threads
Il 17/09/2015 14:00, alister ha scritto: I would like to know more about how many serial ports are connected One real serial port and two virtual serial ports, created by com0com (it's a free virtual serial port for Windows). what the equipment they are connected to does and expects. Raw bytes arranged in a well defined protocol. I'm the author of the protocol and equipments :-) I can see the data being transmitted snowballing & running away in a +ve feedback loop very easily. No, because the byte received by first COM port is forwarded/transmitted to all the OTHERS COM ports in the list. -- https://mail.python.org/mailman/listinfo/python-list
Re: pyserial and threads
Il 17/09/2015 11:42, Chris Angelico ha scritto: On Thu, Sep 17, 2015 at 7:28 PM, pozz <pozzu...@gmail.com> wrote: At startup I open the ports and create and start a thread to manage the receiving. When a byte is received, I call the .write() method for all the other ports. It works, but sometimes it seems to block. I think I haven't used correctly the threads. Seems a fairly reasonable model. From what I'm seeing here, you start a thread to read from each serial port, but then those threads will make blocking writes to all the other serial ports. Is it possible that one of them is getting full? When I do this kind of thing with TCP/IP sockets, I usually end up having to go non-blocking in both directions, and maintaining a buffer of unsent text for each socket. You may find that you need to do the same thing here. How to have a non-blocking write? Maybe the problem happens when port 1 thread is in .read() (it blocks for 1 second) and port 2 thread tries to write one byte (that was just received) to port 1. Where's the code getting blocked? I don't knwo exactly. I can only see no more bytes are received on COM ports. -- https://mail.python.org/mailman/listinfo/python-list
Re: [Newbie] How to wait for asyncronous input
Il 11/08/2012 01:12, Dennis Lee Bieber ha scritto: What you apparently missed is that serial.read() BLOCKs until data is available (unless the port was opened with a read timeout set). [...] serial.read() may, there for, be using select() behind the scenes. Hmm..., so I could open the serial port with timeout=0 so the read(), that runs in a different thread, would block forever, so putting the thread in a sleep state until some bytes arrive. When the main thread wants to close the serial port, the receiving thread can be killed (I don't know why, but I think it will be possible). -- http://mail.python.org/mailman/listinfo/python-list
[Newbie] How to wait for asyncronous input
I'm new to Python and I'm trying to code something to learn the language details. I'm in trouble with asyncronous events, like asyncronous inputs (from serial port, from socket and so on). Let's consider a simple monitor of the traffic on a serial port. I'm using pyserial and I looked at the miniterm example: http://pyserial.svn.sourceforge.net/viewvc/*checkout*/pyserial/trunk/pyserial/serial/tools/miniterm.py The strategy is to create a thread that continuously call read() method while a couple of flags (alive and _reader_alive) are set: def reader(self): try: while self.alive and self._reader_alive: data = character(self.serial.read(1)) Is it an optimized strategy to wait for asyncronous input from serial port? I think in this way we have a thread that is always running and that always asks for new bytes from serial port. In C I should have used the select() on the serial port file descriptor. I think the select() put the thread in a sleep state and wake it up when some bytes are received on the file descriptor specified. It seems the low-level approach of select() is more optimized then the high-level approach of miniterm. -- http://mail.python.org/mailman/listinfo/python-list