Results 1 to 18 of 18

Thread: Serail Port GUI

  1. #1
    Join Date
    Apr 2007
    Posts
    62
    Thanks
    43
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Serail Port GUI

    Hi people,

    I'm an experienced C++ programmer, wanting to do GUI for the first time. I decided to go with Qt 4.2.3 because of its documentation and because it's a commercial product.

    I have written a back-end C++ program that reads GPS, and other modules data via multiple serial ports using Posix threads Win32 and a simple CSerial library, and now I would like to display the data read on the GUI.

    I have done the Qt tutorial, etc...but I dont feel like the tutorial really preps you for the things I'm doing..does anyone have a sample app that display values that are changed via other I/O not from the GUI? (i.e. data constantly changing because of serial port incoming data not because the user clicks something.)

    Since there are multiple threads, I would think there needs to be a mutex around the displayed data ...doesnt it?

    Any help would be greatly appreciated. I actually have more questions but I guess I will just start off like this.

    I'm really excited to be able to do GUI with Qt. Hopefully, in the future I would be able to learn other aspects of Qt as well.

  2. #2
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Serail Port GUI

    Welcome to Qt!
    Since you are not trying to do any I/O with Qt, there is no problem what so ever for you.
    There are many ways do to what you are asking.
    Try to be more specific with your questions -> in regard to what it is you do not understand, and show what you already tried.
    This will help us help you better.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  3. The following user says thank you to high_flyer for this useful post:

    ShaChris23 (17th April 2007)

  4. #3
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Serail Port GUI

    Quote Originally Posted by ShaChris23 View Post
    it's a commercial product.
    Not only and that's probably on of its major advantages... But I guess that's not really the point here...

    Quote Originally Posted by ShaChris23 View Post
    I have written a back-end C++ program that reads GPS, and other modules data via multiple serial ports using Posix threads Win32 and a simple CSerial library, and now I would like to display the data read on the GUI.
    If you want to use Qt is is highly recommended, though not mandatory, to rely on QThread to handle threaded operations. However this remarks only stands if you want to embed your existing program in a GUI and not to provide a graphical front-end communicating with the back end through a CLI.

    Quote Originally Posted by ShaChris23 View Post
    display values that are changed via other I/O not from the GUI? (i.e. data constantly changing because of serial port incoming data not because the user clicks something.)
    This is not a problem... All you have to do is understand OOP, signals and slots and Qt event loop. Then think carefully about the data flow design and everything will be alright...

    Quote Originally Posted by ShaChris23 View Post
    Since there are multiple threads, I would think there needs to be a mutex around the displayed data ...doesn't it?
    It depends on your design... Since the "displayed" data will be owned by the GUI thread (through widgets) there shouldn't be much troubles if data is sent somehow sequentially by working threads through signals/slots mechanism. However if a data structure is shared using, for instance, producer/consumer paradigm, you will probably need to play with QSemaphore, QMutex, ...
    Current Qt projects : QCodeEdit, RotiDeCode

  5. The following user says thank you to fullmetalcoder for this useful post:

    ShaChris23 (17th April 2007)

  6. #4
    Join Date
    Apr 2007
    Posts
    62
    Thanks
    43
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Serial Port GUI

    Hi,

    Here's a snippet from one of my threads. This thread reads a 1Hz GPS data via a serial port. The code below shows code mixed with comments to improve readability, and ignore un-needed technicality.

    Qt Code:
    1. // Open a serial port
    2.  
    3. while( mRunningFlag )
    4. {
    5. // Blocking-Read NMEA message
    6.  
    7. // Now I have some values I would like to display to the GUI.
    8. // For example, these floating-point numbers were updated from the previous read and
    9. // I would like to display it onto the screen
    10. double lat;
    11. double lon;
    12. float utcTime;
    13. }
    To copy to clipboard, switch view to plain text mode 

    What widget/class/function calls should I use to display those values? I think I can do the layout myself since the tutorial #1 taught me about that.

  7. #5
    Join Date
    Apr 2007
    Posts
    62
    Thanks
    43
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Serail Port GUI

    Quote Originally Posted by fullmetalcoder View Post

    This is not a problem... All you have to do is understand OOP, signals and slots and Qt event loop. Then think carefully about the data flow design and everything will be alright... ...
    Hi, yes, I understand signals and slots quite well, though I probably cant use them to their fullest potential yet since I'm new to this. As for the event loop, I'm just learning about it.

    Quote Originally Posted by fullmetalcoder View Post

    It depends on your design... Since the "displayed" data will be owned by the GUI thread (through widgets) there shouldn't be much troubles if data is sent somehow sequentially by working threads through signals/slots mechanism. However if a data structure is shared using, for instance, producer/consumer paradigm, you will probably need to play with QSemaphore, QMutex,
    Since my back-end program was written in straight C++ in a producer/consumer paradigm, I already had mutex to protect the shared resource. So I guess my GUI thread will need to use mutex as well. Can you pass a data structure with signal/slots (is there a shorthand/abbreviation for this (like SS)? From the examples, I have only seen passing of integers. Though I try to avoid passing data around due to performance reason...

  8. #6
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Serail Port GUI

    What widget/class/function calls should I use to display those values? I think I can do the layout myself since the tutorial #1 taught me about that.

    You could use a QTableWidget with three columns: lat, lon and utc time.

    You can transmit these values to the interface via signals.
    You emit one signal from the thread :

    Qt Code:
    1. emit ( lat, lon, utc );
    To copy to clipboard, switch view to plain text mode 

    You receive them in a slot in the interface, and display them.

    The problem remains with the interface responsiveness while it receives this data ( I assume you get a large number of data sets from the serial port ). The signal will be posted as an event to the interface thread and posting too many events in a short period of time can slow the interface down.

    I recommend that you buffer the data in the thread, let's say about 100 data sets, and you emit the whole buffer at once. You can pass a list to the signal, or whatever container you like. This way the table widget will update rarely, with 100 sets at the time.

    What do you think?

    Regards

  9. The following user says thank you to marcel for this useful post:

    ShaChris23 (17th April 2007)

  10. #7
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Serail Port GUI

    Can you pass a data structure with signal/slots (is there a shorthand/abbreviation for this (like SS)? From the examples, I have only seen passing of integers. Though I try to avoid passing data around due to performance reason...
    You have to register your custom type as a meta type to be able to pass it to signals/slots.
    See qRegisterMetaType and Q_DECLARE_METATYPE for more description(in the Assistant).

    Especially:
    Note that if you intend to use the type in queued signal and slot connections, you also have to call qRegisterMetaType() since such connections are resolved at runtime.
    regards

  11. The following user says thank you to marcel for this useful post:

    ShaChris23 (17th April 2007)

  12. #8
    Join Date
    Apr 2007
    Posts
    62
    Thanks
    43
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Serail Port GUI

    Hi Marcel,

    Thanks for the suggestion. Let me show the code that you suggested, and tell me if I misunderstood, or I'm doing anything wrong.



    Qt Code:
    1. // GUI Thread
    2. class GpsGui : public QTableWidget
    3. {
    4.  
    5. public slots:
    6. // Display data using QTableWidget
    7. void displayData( double, double, double );
    8. };
    9.  
    10. // GPS Read thread
    11. double lat, lon, utc;
    12. while( 1 )
    13. {
    14. // Read GPS data & modify lat, lon, utc
    15.  
    16. // send the data
    17. emit( lat, lon, utc );
    18. }
    To copy to clipboard, switch view to plain text mode 

    Is that code skeleton kind of right (both syntax and semantic)? But where should I do the connect( ) to connect the GPS Read thread's signal to the GpsGui's slot?

    Note GPS Read thread and GpsGui are in different files.

    Sorry if the code is just wrong..I'm trying to learn this.

  13. #9
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Serail Port GUI

    ALSO: You need to define a signal that you emit in the thread, like:
    Qt Code:
    1. //in thread definition:
    2. signals:
    3. void values( double, double, double );
    To copy to clipboard, switch view to plain text mode 
    Then you can do in the while loop:
    Qt Code:
    1. emit values( val1, val2, val3 );
    To copy to clipboard, switch view to plain text mode 
    Where do you create the thread? Is it in the Gui?
    If so, try this:

    Qt Code:
    1. connect( workerThread, SIGNAL( values( double, double, double ) ), this, SLOT( displayValues( double, double, double ) ) );
    To copy to clipboard, switch view to plain text mode 
    If it is not, then I suggest implementing the singleton pattern for your main window. Doing this you'll provide a GPSGui::Get() static method.

    You'll be able to do( before actually starting the thread):
    Qt Code:
    1. connect( workerThread, SIGNAL( values( double, double, double ) ), GPSGui->Get(), SLOT( displayValues( double, double, double ) ) );
    To copy to clipboard, switch view to plain text mode 
    Having said this, I assumed your thread is a QThread... Is it? Because if it isn't, you'll need to approach things differently...

    regards
    Last edited by marcel; 17th April 2007 at 19:11.

  14. The following user says thank you to marcel for this useful post:

    ShaChris23 (17th April 2007)

  15. #10
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Serial Port GUI

    Quote Originally Posted by ShaChris23 View Post
    What widget/class/function calls should I use to display those values? I think I can do the layout myself since the tutorial #1 taught me about that.
    It depends on what you want to achieve... marcel suggested a QTableWidget which would be fine in case you want to display kinda log for these three values. However if all you need is these three values to be shown as they are at a given instant then just create QLabel to display the latitude and longitude (also check QString::number(double) to achieve proper display). The time display will probably a little trickier but nothing impossible... QDate, QDateEdit, QTime, QTimeEdit, QDateTime and QDateTimeEdit should help you to deal with this.

    Quote Originally Posted by ShaChris23 View Post
    Since my back-end program was written in straight C++ in a producer/consumer paradigm, I already had mutex to protect the shared resource. So I guess my GUI thread will need to use mutex as well. Can you pass a data structure with signal/slots (is there a shorthand/abbreviation for this (like SS)? From the examples, I have only seen passing of integers. Though I try to avoid passing data around due to performance reason...
    Actually you may not need to mess with QMutex and other Qt threading classes... All you'll need is a class inheriting from QObject which will emit proper signal anytime one of your three values changes. If I understand your design well enough this class should be the class in which the snippet you showed us is defined. Just add members to it :

    Qt Code:
    1. class myClass : public QObject //, ...
    2. {
    3. //...
    4.  
    5. signals:
    6. void timeChanged(double latitude);
    7. void latitudeChanged(double latitude);
    8. void longitudeChanged(double latitude);
    9.  
    10. };
    To copy to clipboard, switch view to plain text mode 
    Then connect these signals to proper slots in the widgets you created (possible changes may be needed for date/time display...) and place the following code in your loop :

    Qt Code:
    1. // when latitude changes :
    2. emit latitudeChanged(latitude);
    3.  
    4. // when longitude changes :
    5. emit longitudeChanged(longitude);
    6.  
    7. // when time changes :
    8. emit timeChanged(time);
    To copy to clipboard, switch view to plain text mode 
    Hope this helps.
    Last edited by fullmetalcoder; 17th April 2007 at 21:35. Reason: reformatted to look better
    Current Qt projects : QCodeEdit, RotiDeCode

  16. The following user says thank you to fullmetalcoder for this useful post:

    ShaChris23 (17th April 2007)

  17. #11
    Join Date
    Apr 2007
    Posts
    62
    Thanks
    43
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Serial Port GUI

    Hi fullmetalcoder,

    Yes, you understood what I wanted to do right. Now that those signals are emitted, then on the GUI side, I can do the following right?

    Qt Code:
    1. // First, somewhere before the threads are started, I do (say..just for latitude for now)
    2. connect( myClass, SIGNAL(latitiudeChanged(double)), MyGui, SLOT(displayLat) );
    3.  
    4. // Then here's the implementation of MyGUI
    5. class MyGui : public QLabel
    6. {
    7. public slots:
    8. void displayLat( double lat );
    9. };
    To copy to clipboard, switch view to plain text mode 

    What would the function definition of void displayLat( double lat ) be like so that I can display the current latitude?

  18. #12
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Serail Port GUI

    OK, I've read what you posted before and I concluded your threads are not QThreads. Because of this you cannot use the signals/slots mechanism.
    In this case you'll have to use straight events . This will make it easier passing custom types.

    In the GUI
    Qt Code:
    1. bool GPSGui::event( QEvent* e )
    2. {
    3. if( e->type() == QEvent::User )
    4. {
    5. CMyEvent *me = dynamic_cast<CMyEvent*>(e);
    6. if( me )
    7. {
    8. updateTableWidget( me->dataBuffer );
    9. delete me->dataBuffer;
    10. me->dataBuffer = NULL;
    11. e->accept();
    12. return true;
    13. }
    14. }
    15. return QMainWindow::event(e);
    16. }
    To copy to clipboard, switch view to plain text mode 

    In the thread:

    Qt Code:
    1. float v1, v2, v3;
    2. while(1)
    3. {
    4. ....
    5. //Fill the buffer with data sets
    6. QApplication::postEvent( GPSGui::Get(), new CMyEvent( dataBuffer ) );
    7. }
    To copy to clipboard, switch view to plain text mode 

    If you agree, then I'll show you how to implement the event, which is not really hard.
    Note that dataBuffer (in the thread ) must be allocated on the heap and deleted in the GUI.

    Regards

  19. The following user says thank you to marcel for this useful post:

    ShaChris23 (17th April 2007)

  20. #13
    Join Date
    Apr 2007
    Posts
    62
    Thanks
    43
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Serail Port GUI

    Hi Marcel...

    I create all the the threads in my main(). Perhaps Qt's thread instantiation is done in a different fashion, and I havent looked into it yet. I've been focusing on just the GUI part...

    I'm using Posix threads...
    Right now, my program is kinda like..

    Qt Code:
    1. int main()
    2. {
    3. // Initialize all the data classes
    4.  
    5. // Create threads...
    6. }
    7.  
    8. void* threadFunc1(void* param)
    9. {
    10. while(1)
    11. // ...
    12.  
    13. }
    14.  
    15. void* threadFunc2(void* param)
    16. {
    17. while(1)
    18. // ...
    19. }
    To copy to clipboard, switch view to plain text mode 

  21. #14
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Serail Port GUI

    Yes, and this is why you have to use events/event handling instead of signals/slots...Which is pretty much the same in this case, just more to code...

    Unless you want to make your threads QThreads...
    You must understand that only classes derived from QObjects ( in this case must be QThread ) can emit signals ( or receive, but to receive you will also need to start an event loop in your thread with exec() );


    After all, it is not that hard what you're trying to achieve... Shouldn't take more than 2-3 hours to get something working...

    Regards

  22. The following user says thank you to marcel for this useful post:

    ShaChris23 (17th April 2007)

  23. #15
    Join Date
    Apr 2007
    Posts
    62
    Thanks
    43
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Serail Port GUI

    Hi Marcel,

    I dont fully understand the event code that you just implemented...however, please do show how to implement the event if you would like just so I will get a better understanding.

    I'm also going to look up on QThread example...maybe it's worth it to just convert my design to QThreads.

  24. #16
    Join Date
    Apr 2007
    Posts
    62
    Thanks
    43
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Serail Port GUI

    Hi Marcel..

    The QThread is very similar to Java's ..so I dont think it's going to be a problem, I can certainly use it. Sorry to keep switching back and forth.

  25. #17
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Serail Port GUI

    Sure...
    If you decide to convert to QThreads then you won't need the custom events anymore. But for the sake of completeness...

    Declaration:
    Qt Code:
    1. #include <QEvent>
    2.  
    3. class CMyEvent : public QEvent
    4. {
    5. Q_OBJECT
    6.  
    7. public:
    8. CMyEvent( BufferStructure* );
    9. ~CMyEvent();
    10.  
    11. BufferStructure* dataSets;
    12. }
    To copy to clipboard, switch view to plain text mode 

    Definition:
    Qt Code:
    1. #define EVENT_TYPE (QEvent::User)
    2. CMyEvent::CMyEvent( BufferStructure* dSets )
    3. : QEvent( EVENT_TYPE )
    4. {
    5. dataSets = new BUfferStructure( *dSets );
    6. }
    7.  
    8. CMyEvent::~CMyEvent()
    9. {
    10. delete dataSets;
    11. }
    To copy to clipboard, switch view to plain text mode 

    Given the fact that dataSets is now deleted in the destructor, it shouldn't be deleted in the event of GPSGui, as I did it earlier.

    So, this is it.

    Regards.

  26. The following user says thank you to marcel for this useful post:

    ShaChris23 (17th April 2007)

  27. #18
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Serail Port GUI

    The QThread is very similar to Java's ..so I dont think it's going to be a problem, I can certainly use it. Sorry to keep switching back and forth.
    No problem...
    I guess you can now just use signals, and lose the custom events...

  28. The following user says thank you to marcel for this useful post:

    ShaChris23 (17th April 2007)

Similar Threads

  1. Serial Port communication
    By mgurbuz in forum Qt Programming
    Replies: 12
    Last Post: 22nd January 2011, 02:38
  2. Replies: 6
    Last Post: 18th April 2007, 15:04
  3. list port of computer
    By manhds in forum Qt Programming
    Replies: 2
    Last Post: 12th March 2007, 09:04
  4. trayicon port to QT4
    By ykohn in forum Qt Programming
    Replies: 10
    Last Post: 21st April 2006, 15:11
  5. Replies: 16
    Last Post: 7th March 2006, 15:57

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.