Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Synchronizing between a local and remote GUI
Forum Updated to NodeBB v4.3 + New Features

Synchronizing between a local and remote GUI

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 4 Posters 710 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    andyP
    wrote on last edited by andyP
    #1

    Consider the following GUI:

    enter image description here

    when the user press the + button the value is incremented to 6.

    However on another computer another user is running the same GUI.

    The two GUIs have to stay in sync.
    If one of the users press the + button the value should be updated for both GUIs.

    The remote GUI, the client, communicate with the local server via a simple protocol.
    The communication takes the form of a cmd sent from the client and a response sent from the server. There are two commands:

    1. cmd:"GET_VALUE", response: "5"
    2. cmd: "INCREMENT", response: "OK"
    

    Unfortunately the client has to poll GET_VALUE to be notified, but the protocol albeit flawed can not be changed.
    Also the response to the cmds have to be returned within a time limit (100 ms I think).

    How can I implement this in Qt, C++?

    So far I have come up with the following classes (rough outline):

    class Model {
    public:
    	std::atomic<int> m_value;
    };
    
    class Widget : public QWidget {
    public slots:
    	void incrementClickedLocally(); // must update Model::m_value somehow
    	void valueChangedFromModel(int value); // will update the QLineEdit
    };
    
    // Reads synchronously from TCP/IP using WinSocket and works on the Model 
    class RemoteHandler : public QThread {
    private:
    	void run override();
    };
    

    I would like to use signals/slots to communicate across the threads.
    However it seems that the RemoteHandler can not use signal/slots to get the Model::m_value since slots can not have return types?

    Further it would be convenient to emit a valueChanged signal from Model to notify Widget. However in order to do that Model must be a QObject.
    It seems that when Model becomes a QObject there are many potential thread problems I have to look out for?
    As it is Model is threadsafe. I can therefore request Model::m_value directly from the non main thread in RemoteHandler while the Widget may be accessing the same variable simultaneously from the main thread.

    JonBJ Pl45m4P artwawA 3 Replies Last reply
    0
    • A andyP

      @JonB : Thank you. I was just thinking the same thing. I think my reason was that the client may hammer the server with GET_VALUE messages. The server also runs OpenGL in the main thread. I was worried that if the messages from the client was processed in the main thread the OpenGL visualization would not be smooth. Not sure if this is the case though. I should probably test this,

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #7

      @andyP said in Synchronizing between a local and remote GUI:

      I think my reason was that the client may hammer the server with GET_VALUE messages

      It won't. How many/frequently messages do you imagine a UI executes, e.g. in response to a user action pressing a button. It's minuscule compared to e.g. the speed of TCP/IP messages....

      std::atomic<>, QAtomicInt, and all your questions about polling, flags etc.: You won't be needing any of this stuff once you realise threads are not the way to go.....

      A 1 Reply Last reply
      2
      • A andyP

        Consider the following GUI:

        enter image description here

        when the user press the + button the value is incremented to 6.

        However on another computer another user is running the same GUI.

        The two GUIs have to stay in sync.
        If one of the users press the + button the value should be updated for both GUIs.

        The remote GUI, the client, communicate with the local server via a simple protocol.
        The communication takes the form of a cmd sent from the client and a response sent from the server. There are two commands:

        1. cmd:"GET_VALUE", response: "5"
        2. cmd: "INCREMENT", response: "OK"
        

        Unfortunately the client has to poll GET_VALUE to be notified, but the protocol albeit flawed can not be changed.
        Also the response to the cmds have to be returned within a time limit (100 ms I think).

        How can I implement this in Qt, C++?

        So far I have come up with the following classes (rough outline):

        class Model {
        public:
        	std::atomic<int> m_value;
        };
        
        class Widget : public QWidget {
        public slots:
        	void incrementClickedLocally(); // must update Model::m_value somehow
        	void valueChangedFromModel(int value); // will update the QLineEdit
        };
        
        // Reads synchronously from TCP/IP using WinSocket and works on the Model 
        class RemoteHandler : public QThread {
        private:
        	void run override();
        };
        

        I would like to use signals/slots to communicate across the threads.
        However it seems that the RemoteHandler can not use signal/slots to get the Model::m_value since slots can not have return types?

        Further it would be convenient to emit a valueChanged signal from Model to notify Widget. However in order to do that Model must be a QObject.
        It seems that when Model becomes a QObject there are many potential thread problems I have to look out for?
        As it is Model is threadsafe. I can therefore request Model::m_value directly from the non main thread in RemoteHandler while the Widget may be accessing the same variable simultaneously from the main thread.

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by
        #2

        @andyP
        Why do you have any threads at all? Without would simplify the task a lot. Qt TCP socket handling is designed to be asynchronous.

        A 1 Reply Last reply
        1
        • A andyP

          Consider the following GUI:

          enter image description here

          when the user press the + button the value is incremented to 6.

          However on another computer another user is running the same GUI.

          The two GUIs have to stay in sync.
          If one of the users press the + button the value should be updated for both GUIs.

          The remote GUI, the client, communicate with the local server via a simple protocol.
          The communication takes the form of a cmd sent from the client and a response sent from the server. There are two commands:

          1. cmd:"GET_VALUE", response: "5"
          2. cmd: "INCREMENT", response: "OK"
          

          Unfortunately the client has to poll GET_VALUE to be notified, but the protocol albeit flawed can not be changed.
          Also the response to the cmds have to be returned within a time limit (100 ms I think).

          How can I implement this in Qt, C++?

          So far I have come up with the following classes (rough outline):

          class Model {
          public:
          	std::atomic<int> m_value;
          };
          
          class Widget : public QWidget {
          public slots:
          	void incrementClickedLocally(); // must update Model::m_value somehow
          	void valueChangedFromModel(int value); // will update the QLineEdit
          };
          
          // Reads synchronously from TCP/IP using WinSocket and works on the Model 
          class RemoteHandler : public QThread {
          private:
          	void run override();
          };
          

          I would like to use signals/slots to communicate across the threads.
          However it seems that the RemoteHandler can not use signal/slots to get the Model::m_value since slots can not have return types?

          Further it would be convenient to emit a valueChanged signal from Model to notify Widget. However in order to do that Model must be a QObject.
          It seems that when Model becomes a QObject there are many potential thread problems I have to look out for?
          As it is Model is threadsafe. I can therefore request Model::m_value directly from the non main thread in RemoteHandler while the Widget may be accessing the same variable simultaneously from the main thread.

          Pl45m4P Online
          Pl45m4P Online
          Pl45m4
          wrote on last edited by
          #3

          @andyP said in Synchronizing between a local and remote GUI:

          However it seems that the RemoteHandler can not use signal/slots to get the Model::m_value since slots can not have return types?

          Why do you need a return type for this? Send a signal (request) to the model to get the current value... In your model you add some slot like onValueRequested and in there you send the value back to your request-"starter" (-> 2-way connection).
          Unless there's a better way, but I dont know much about your app design or structure.


          If debugging is the process of removing software bugs, then programming must be the process of putting them in.

          ~E. W. Dijkstra

          A 1 Reply Last reply
          1
          • JonBJ JonB

            @andyP
            Why do you have any threads at all? Without would simplify the task a lot. Qt TCP socket handling is designed to be asynchronous.

            A Offline
            A Offline
            andyP
            wrote on last edited by andyP
            #4

            @JonB : Thank you. I was just thinking the same thing. I think my reason was that the client may hammer the server with GET_VALUE messages. The server also runs OpenGL in the main thread. I was worried that if the messages from the client was processed in the main thread the OpenGL visualization would not be smooth. Not sure if this is the case though. I should probably test this,

            JonBJ 1 Reply Last reply
            0
            • Pl45m4P Pl45m4

              @andyP said in Synchronizing between a local and remote GUI:

              However it seems that the RemoteHandler can not use signal/slots to get the Model::m_value since slots can not have return types?

              Why do you need a return type for this? Send a signal (request) to the model to get the current value... In your model you add some slot like onValueRequested and in there you send the value back to your request-"starter" (-> 2-way connection).
              Unless there's a better way, but I dont know much about your app design or structure.

              A Offline
              A Offline
              andyP
              wrote on last edited by andyP
              #5

              @Pl45m4 : Thank you. But how do I send the value back to RemoteHandler? From what I understand it is adviced against subclasses of QThread having slots? I guess I could introduce a std::atomic<bool> m_answerReadyand std::atomic<int> m_value variable in the RemoteHandler class. After the RemoteHandler had sent a requestValue signal it would go into a poll loop where it would be checking the m_answerReady flag until it changes. That may work.

              Pl45m4P 1 Reply Last reply
              0
              • A andyP

                @Pl45m4 : Thank you. But how do I send the value back to RemoteHandler? From what I understand it is adviced against subclasses of QThread having slots? I guess I could introduce a std::atomic<bool> m_answerReadyand std::atomic<int> m_value variable in the RemoteHandler class. After the RemoteHandler had sent a requestValue signal it would go into a poll loop where it would be checking the m_answerReady flag until it changes. That may work.

                Pl45m4P Online
                Pl45m4P Online
                Pl45m4
                wrote on last edited by
                #6

                @andyP

                With @JonB 's suggestion, you dont have to worry about threads at all, but can tell if it's gonna work for you.

                Fyi: Qt has also its own type QAtomicInt (any other atomic data type is possible too).

                • https://doc.qt.io/qt-5/qatomicint.html

                If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                ~E. W. Dijkstra

                1 Reply Last reply
                0
                • A andyP

                  @JonB : Thank you. I was just thinking the same thing. I think my reason was that the client may hammer the server with GET_VALUE messages. The server also runs OpenGL in the main thread. I was worried that if the messages from the client was processed in the main thread the OpenGL visualization would not be smooth. Not sure if this is the case though. I should probably test this,

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by
                  #7

                  @andyP said in Synchronizing between a local and remote GUI:

                  I think my reason was that the client may hammer the server with GET_VALUE messages

                  It won't. How many/frequently messages do you imagine a UI executes, e.g. in response to a user action pressing a button. It's minuscule compared to e.g. the speed of TCP/IP messages....

                  std::atomic<>, QAtomicInt, and all your questions about polling, flags etc.: You won't be needing any of this stuff once you realise threads are not the way to go.....

                  A 1 Reply Last reply
                  2
                  • A andyP

                    Consider the following GUI:

                    enter image description here

                    when the user press the + button the value is incremented to 6.

                    However on another computer another user is running the same GUI.

                    The two GUIs have to stay in sync.
                    If one of the users press the + button the value should be updated for both GUIs.

                    The remote GUI, the client, communicate with the local server via a simple protocol.
                    The communication takes the form of a cmd sent from the client and a response sent from the server. There are two commands:

                    1. cmd:"GET_VALUE", response: "5"
                    2. cmd: "INCREMENT", response: "OK"
                    

                    Unfortunately the client has to poll GET_VALUE to be notified, but the protocol albeit flawed can not be changed.
                    Also the response to the cmds have to be returned within a time limit (100 ms I think).

                    How can I implement this in Qt, C++?

                    So far I have come up with the following classes (rough outline):

                    class Model {
                    public:
                    	std::atomic<int> m_value;
                    };
                    
                    class Widget : public QWidget {
                    public slots:
                    	void incrementClickedLocally(); // must update Model::m_value somehow
                    	void valueChangedFromModel(int value); // will update the QLineEdit
                    };
                    
                    // Reads synchronously from TCP/IP using WinSocket and works on the Model 
                    class RemoteHandler : public QThread {
                    private:
                    	void run override();
                    };
                    

                    I would like to use signals/slots to communicate across the threads.
                    However it seems that the RemoteHandler can not use signal/slots to get the Model::m_value since slots can not have return types?

                    Further it would be convenient to emit a valueChanged signal from Model to notify Widget. However in order to do that Model must be a QObject.
                    It seems that when Model becomes a QObject there are many potential thread problems I have to look out for?
                    As it is Model is threadsafe. I can therefore request Model::m_value directly from the non main thread in RemoteHandler while the Widget may be accessing the same variable simultaneously from the main thread.

                    artwawA Offline
                    artwawA Offline
                    artwaw
                    wrote on last edited by
                    #8

                    @andyP Sounds like a task for Qt Remote Objects?

                    For more information please re-read.

                    Kind Regards,
                    Artur

                    1 Reply Last reply
                    1
                    • JonBJ JonB

                      @andyP said in Synchronizing between a local and remote GUI:

                      I think my reason was that the client may hammer the server with GET_VALUE messages

                      It won't. How many/frequently messages do you imagine a UI executes, e.g. in response to a user action pressing a button. It's minuscule compared to e.g. the speed of TCP/IP messages....

                      std::atomic<>, QAtomicInt, and all your questions about polling, flags etc.: You won't be needing any of this stuff once you realise threads are not the way to go.....

                      A Offline
                      A Offline
                      andyP
                      wrote on last edited by
                      #9

                      @JonB : I tried your suggestion and it appears to be working fine. Thank you!

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved