0

i am working with pyside and trying to do asynchronous serial communication with it but the QtSerialPort is not yet available, i have used pyserial and moved the serial communication to another thread using moveToThread() but i have to check if there there is a message regularly, so i used a QTimer to handle that every 200 ms,but this solution is over kill, if i can have Qt send a readyRead signal every time there is data available, the question is precisely is :

is there is a ready module that help with without breaking my whole code depenedency on pyside? if there isn't, what is your tips for quickly implementing one? thanks in advance.

zmo
  • 24,463
  • 4
  • 54
  • 90
Mohammed Talat
  • 77
  • 2
  • 12

2 Answers2

1

just avoid using qtserialport, and you're right to use pyserial. A good way to go would be to use pyserial as you thought yourself, but run it as another process (using multiprocessing module), and using Queues to pass around input/output from the serial port.

In the pyside code, you can register a function that acts like an infinite loop, checking for data input in the queue, and do stuff (basically, fire serial incoming event) when data is coming in. You can even use python-async!

That way, you keep your code compact within a single codebase, but loosely coupled in terms of features, without extra bloat having a simple queue as IPC.

Because threading in python can be tricky, because of the global interpreter lock, and even more as you've got the Qt threading model (and eventloop) working alongside python's. As a rule of thumb: don't mix bananas and tomatoes.

Community
  • 1
  • 1
zmo
  • 24,463
  • 4
  • 54
  • 90
  • can you elaborate a little on why not using `QtSerialPort`, and yes i used Qt threading with pyserial but i simply emit a signal when there is data available – Mohammed Talat Mar 20 '17 at 16:48
  • well, long story short, it's a framework with a lot of technological debt, is overengineered, which developers are having a hard time to communicate, and has too many bugs. Add to that the overhead of the python abstraction, and *there be dragons*. – zmo Mar 20 '17 at 17:19
  • I had a look at the qserialport source written in cpp and it seems very well written and organized and approved in the qt library I might consider developing this module using cpp – Mohammed Talat Mar 20 '17 at 17:27
  • Well, trust the experience of a random guy from Internet whose had a bitter experience with it, tried to submit a couple of patches which ended in an endless design debate. Ultimately I had to switch mid-project to [asio](http://think-async.com/Asio) which offers a portable and properly *working* solution to handle serialports. The only thing I'm still using `QtSerialPort` for, is the `QtSerialPortInfo` class that can provide information about available ports cross-platform. – zmo Mar 20 '17 at 17:50
  • :), well, will take your your advise seriously, i was really interested in the way it handle receiving data asynchronously and your suggested solution doesn't offer another way to accomplish this, i think cheching for available data every 200ms or so is not agood idea, if you can advise on how to implement similar thing using qiodevice that would be appreciated, thank you – Mohammed Talat Mar 20 '17 at 17:59
  • well, that's not how it shall work, you should have an infinite loop thread in the pyside process that blocks on `data = queue.get()` and emits a signal with `data` as parameter each time it receives something. Then when you'll port your code to C++ you can use different strategies to use Asio… you can get inspiration from [code like this one](https://github.com/peper0/qtasio). – zmo Mar 20 '17 at 18:06
0

i found a workaround which is using PyQt5 serial port module and building a standalone module that handle serial communication and communicating with my main application using Inter Process Communication (IPC) or a local network socket, that will do it for now, and i have no problem open sourcing this serial communication module, and my main application is intact.

Mohammed Talat
  • 77
  • 2
  • 12