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. Using QThread , Signal() , Slot() So GUI won't freeze
Forum Updated to NodeBB v4.3 + New Features

Using QThread , Signal() , Slot() So GUI won't freeze

Scheduled Pinned Locked Moved Unsolved General and Desktop
42 Posts 8 Posters 6.3k Views 4 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.
  • M mpergand

    @__d4ve__ said in Using QThread , Signal() , Slot() So GUI won't freeze:

    pcap_loop(handle ,NUM_PACKETS_TO_CAPTURE ,packet_handler , nullptr);

    pass this, instead of nullptr.

    M Offline
    M Offline
    mpergand
    wrote on last edited by
    #21

    @mpergand said in Using QThread , Signal() , Slot() So GUI won't freeze:

    pcap_loop(handle ,NUM_PACKETS_TO_CAPTURE ,packet_handler , this);
    

    and in the callback:

    void workerobject::packet_handler(u_char* user_data, const struct pcap_pkthdr* packet_header, const u_char* packet_data)
    {
    ...
    WorkerObject* wo=qobject_cast<WorkerObject*>(user_data);
    assert(wo);
    wo->update_gui(...);
    
    _ 1 Reply Last reply
    0
    • M mpergand

      @mpergand said in Using QThread , Signal() , Slot() So GUI won't freeze:

      pcap_loop(handle ,NUM_PACKETS_TO_CAPTURE ,packet_handler , this);
      

      and in the callback:

      void workerobject::packet_handler(u_char* user_data, const struct pcap_pkthdr* packet_header, const u_char* packet_data)
      {
      ...
      WorkerObject* wo=qobject_cast<WorkerObject*>(user_data);
      assert(wo);
      wo->update_gui(...);
      
      _ Offline
      _ Offline
      __d4ve__
      wrote on last edited by
      #22

      @mpergand Your solution doesn't work / not understandable

      packet_handler function just process the data and I use emit to pass the processed data to function which will update the GUI the main issue i encounter here is with static / not static functions errors i mentioned above , any way thank you for trying

      1 Reply Last reply
      0
      • _ Offline
        _ Offline
        __d4ve__
        wrote on last edited by
        #23
        This post is deleted!
        1 Reply Last reply
        0
        • _ Offline
          _ Offline
          __d4ve__
          wrote on last edited by
          #24

          I have error with :

          pcap_loop(handle, NUM_PACKETS_TO_CAPTURE, packet_handler, nullptr);
          
          the error :
          C:\Users\Dave\Desktop\C++ Exercises\Qt Creator Projects\Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:88: error: Reference to non-static member function must be called
          

          full code here : Qt Packet Viewer Code

          _ 1 Reply Last reply
          0
          • _ __d4ve__

            I have error with :

            pcap_loop(handle, NUM_PACKETS_TO_CAPTURE, packet_handler, nullptr);
            
            the error :
            C:\Users\Dave\Desktop\C++ Exercises\Qt Creator Projects\Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:88: error: Reference to non-static member function must be called
            

            full code here : Qt Packet Viewer Code

            _ Offline
            _ Offline
            __d4ve__
            wrote on last edited by __d4ve__
            #25

            @__d4ve__

            Sum up of all the errors :

            
            \Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:55: error: C3861: 'update_gui': identifier not found
            
            \Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:88: error: C3867: 'workerobject::packet_handler': non-standard syntax; use '&' to create a pointer to member
            
            \Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:55: error: Use of undeclared identifier 'update_gui'
            
            \Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:88: error: Reference to non-static member function must be called
            
            jsulmJ 1 Reply Last reply
            0
            • _ __d4ve__

              @__d4ve__

              Sum up of all the errors :

              
              \Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:55: error: C3861: 'update_gui': identifier not found
              
              \Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:88: error: C3867: 'workerobject::packet_handler': non-standard syntax; use '&' to create a pointer to member
              
              \Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:55: error: Use of undeclared identifier 'update_gui'
              
              \Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:88: error: Reference to non-static member function must be called
              
              jsulmJ Offline
              jsulmJ Offline
              jsulm
              Lifetime Qt Champion
              wrote on last edited by
              #26

              @__d4ve__ said in Using QThread , Signal() , Slot() So GUI won't freeze:

              \Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:55: error: C3861: 'update_gui': identifier not found

              Please show the code which causes this error...

              https://forum.qt.io/topic/113070/qt-code-of-conduct

              _ 1 Reply Last reply
              1
              • jsulmJ jsulm

                @__d4ve__ said in Using QThread , Signal() , Slot() So GUI won't freeze:

                \Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:55: error: C3861: 'update_gui': identifier not found

                Please show the code which causes this error...

                _ Offline
                _ Offline
                __d4ve__
                wrote on last edited by
                #27

                @jsulm
                full code here : Qt Packet Viewer Code

                seems that workerobject.cpp does the error

                jsulmJ 1 Reply Last reply
                0
                • _ __d4ve__

                  @jsulm
                  full code here : Qt Packet Viewer Code

                  seems that workerobject.cpp does the error

                  jsulmJ Offline
                  jsulmJ Offline
                  jsulm
                  Lifetime Qt Champion
                  wrote on last edited by
                  #28

                  @__d4ve__ Sorry, but I'm not going to search in that link for relevant parts. You can simply post the code (and only that code) which causes this errors...

                  https://forum.qt.io/topic/113070/qt-code-of-conduct

                  _ 1 Reply Last reply
                  3
                  • jsulmJ jsulm

                    @__d4ve__ Sorry, but I'm not going to search in that link for relevant parts. You can simply post the code (and only that code) which causes this errors...

                    _ Offline
                    _ Offline
                    __d4ve__
                    wrote on last edited by
                    #29

                    @jsulm
                    The error occurs with packet_handler & pcap_loop(handle, NUM_PACKETS_TO_CAPTURE, packet_handler, nullptr);
                    which is calling it

                    void packet_handler(u_char* user_data, const struct pcap_pkthdr* packet_header, const u_char* packet_data)
                    {
                        std::stringstream packetInfo;
                    
                        // Add packet information to the stringstream
                        packetInfo << std::endl;
                        packetInfo << "Packet Information:" << std::endl;
                        packetInfo << "Capture Length: " << std::setw(5) << packet_header->caplen << std::endl;
                        packetInfo << "Packet Length: " << std::setw(5) << packet_header->len << std::endl;
                        packetInfo << "Packet Data:" << std::endl;
                    
                        // Print packet data as hexadecimal and ASCII
                        int byte_count = 0;
                        for (unsigned int i = 0; i < packet_header->caplen; i++)
                        {
                            packetInfo << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(packet_data[i]) << " ";
                            byte_count++;
                    
                            // Add extra space after every 8 bytes for better readability
                            if (byte_count % 8 == 0)
                                packetInfo << " ";
                    
                            // Add newline after every 16 bytes and print ASCII representation
                            if (byte_count % 16 == 0)
                            {
                                packetInfo << "| ";
                                for (unsigned int j = i - 15; j <= i; j++)
                                {
                                    if (packet_data[j] >= 32 && packet_data[j] <= 126)
                                        packetInfo << static_cast<char>(packet_data[j]);
                                    else
                                        packetInfo << ".";
                                }
                                packetInfo << std::endl;
                            }
                        }
                    
                        std::string packetInfoString = packetInfo.str();
                        QString packetInfoQString = QString::fromStdString(packetInfoString);
                    
                        QMutexLocker locker(&Mutex);
                        std::cout << packetInfoString << std::endl;
                       // emit packetCaptured(packetInfoQString);
                    
                        emit update_gui(packetInfoQString);
                    }
                    
                    // loop through packets with choosen device ---- should add variable device
                    // The pcap_loop starter // in current stat device name need to be inputed
                    void workerobject::packet_looper()
                    {
                        //QString selectedDev_qt; // Initialize it with the selected device name
                    
                        char errbuf[PCAP_ERRBUF_SIZE];
                        pcap_if_t* alldevs = nullptr;
                        pcap_if_t* selectedDev = nullptr;
                    
                        // Iterate over the list of interfaces and find the selected adapter
                        for (pcap_if_t* dev = alldevs; dev != nullptr; dev = dev->next)
                        {
                            if (selectedDev_qt == dev->description)
                            {
                                selectedDev = dev;
                                break;
                            }
                        }
                    
                        pcap_t* handle = pcap_open_live(selectedDev->name, BUFSIZ, 1, 1000, errbuf);
                        if (handle == nullptr)
                        {
                            std::cerr << "Error opening interface for packet capture: " << errbuf << std::endl;
                            pcap_freealldevs(alldevs);
                            return; // Stop further execution if opening handle fails
                        }
                    
                        QMutexLocker unlock(&Mutex);
                    
                        pcap_loop(handle, NUM_PACKETS_TO_CAPTURE, packet_handler, nullptr);
                    
                        // Close the packet capture handle
                        pcap_close(handle);
                    
                        // Free the allocated memory for the interface list
                        pcap_freealldevs(alldevs);
                    }
                    
                    JonBJ 1 Reply Last reply
                    0
                    • _ __d4ve__

                      @jsulm
                      The error occurs with packet_handler & pcap_loop(handle, NUM_PACKETS_TO_CAPTURE, packet_handler, nullptr);
                      which is calling it

                      void packet_handler(u_char* user_data, const struct pcap_pkthdr* packet_header, const u_char* packet_data)
                      {
                          std::stringstream packetInfo;
                      
                          // Add packet information to the stringstream
                          packetInfo << std::endl;
                          packetInfo << "Packet Information:" << std::endl;
                          packetInfo << "Capture Length: " << std::setw(5) << packet_header->caplen << std::endl;
                          packetInfo << "Packet Length: " << std::setw(5) << packet_header->len << std::endl;
                          packetInfo << "Packet Data:" << std::endl;
                      
                          // Print packet data as hexadecimal and ASCII
                          int byte_count = 0;
                          for (unsigned int i = 0; i < packet_header->caplen; i++)
                          {
                              packetInfo << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(packet_data[i]) << " ";
                              byte_count++;
                      
                              // Add extra space after every 8 bytes for better readability
                              if (byte_count % 8 == 0)
                                  packetInfo << " ";
                      
                              // Add newline after every 16 bytes and print ASCII representation
                              if (byte_count % 16 == 0)
                              {
                                  packetInfo << "| ";
                                  for (unsigned int j = i - 15; j <= i; j++)
                                  {
                                      if (packet_data[j] >= 32 && packet_data[j] <= 126)
                                          packetInfo << static_cast<char>(packet_data[j]);
                                      else
                                          packetInfo << ".";
                                  }
                                  packetInfo << std::endl;
                              }
                          }
                      
                          std::string packetInfoString = packetInfo.str();
                          QString packetInfoQString = QString::fromStdString(packetInfoString);
                      
                          QMutexLocker locker(&Mutex);
                          std::cout << packetInfoString << std::endl;
                         // emit packetCaptured(packetInfoQString);
                      
                          emit update_gui(packetInfoQString);
                      }
                      
                      // loop through packets with choosen device ---- should add variable device
                      // The pcap_loop starter // in current stat device name need to be inputed
                      void workerobject::packet_looper()
                      {
                          //QString selectedDev_qt; // Initialize it with the selected device name
                      
                          char errbuf[PCAP_ERRBUF_SIZE];
                          pcap_if_t* alldevs = nullptr;
                          pcap_if_t* selectedDev = nullptr;
                      
                          // Iterate over the list of interfaces and find the selected adapter
                          for (pcap_if_t* dev = alldevs; dev != nullptr; dev = dev->next)
                          {
                              if (selectedDev_qt == dev->description)
                              {
                                  selectedDev = dev;
                                  break;
                              }
                          }
                      
                          pcap_t* handle = pcap_open_live(selectedDev->name, BUFSIZ, 1, 1000, errbuf);
                          if (handle == nullptr)
                          {
                              std::cerr << "Error opening interface for packet capture: " << errbuf << std::endl;
                              pcap_freealldevs(alldevs);
                              return; // Stop further execution if opening handle fails
                          }
                      
                          QMutexLocker unlock(&Mutex);
                      
                          pcap_loop(handle, NUM_PACKETS_TO_CAPTURE, packet_handler, nullptr);
                      
                          // Close the packet capture handle
                          pcap_close(handle);
                      
                          // Free the allocated memory for the interface list
                          pcap_freealldevs(alldevs);
                      }
                      
                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by JonB
                      #30

                      @__d4ve__
                      Sorry, what does "which is calling it" have anything to do with error? It is a compiler error for an undefined identifier.

                      What are lines #55 and #88 in workerobject.cpp? That is what we need to know!

                      If it errors on the line

                      emit update_gui(packetInfoQString);
                      

                      you show above (but I only see one occurrence, how can that be both lines?) then update_gui() is not declared to the compiler at that point.

                      _ JonBJ 2 Replies Last reply
                      0
                      • JonBJ JonB

                        @__d4ve__
                        Sorry, what does "which is calling it" have anything to do with error? It is a compiler error for an undefined identifier.

                        What are lines #55 and #88 in workerobject.cpp? That is what we need to know!

                        If it errors on the line

                        emit update_gui(packetInfoQString);
                        

                        you show above (but I only see one occurrence, how can that be both lines?) then update_gui() is not declared to the compiler at that point.

                        _ Offline
                        _ Offline
                        __d4ve__
                        wrote on last edited by
                        #31

                        @JonB
                        pcap_loop calls packet_handler -> emits update_gui

                        1 Reply Last reply
                        0
                        • JonBJ JonB

                          @__d4ve__
                          Sorry, what does "which is calling it" have anything to do with error? It is a compiler error for an undefined identifier.

                          What are lines #55 and #88 in workerobject.cpp? That is what we need to know!

                          If it errors on the line

                          emit update_gui(packetInfoQString);
                          

                          you show above (but I only see one occurrence, how can that be both lines?) then update_gui() is not declared to the compiler at that point.

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

                          @JonB said in Using QThread , Signal() , Slot() So GUI won't freeze:

                          What are lines #55 and #88 in workerobject.cpp? That is what we need to know!

                          I give up and am out....

                          1 Reply Last reply
                          2
                          • _ Offline
                            _ Offline
                            __d4ve__
                            wrote on last edited by
                            #33

                            I'm wondering if there is a better way to accomplish this task maybe using Tins .. but that's and issue by itself

                            Pl45m4P 1 Reply Last reply
                            0
                            • _ __d4ve__

                              I'm wondering if there is a better way to accomplish this task maybe using Tins .. but that's and issue by itself

                              Pl45m4P Offline
                              Pl45m4P Offline
                              Pl45m4
                              wrote on last edited by
                              #34

                              @__d4ve__ said in Using QThread , Signal() , Slot() So GUI won't freeze:

                              I'm wondering if there is a better way to accomplish this task maybe using Tins

                              How should this change something? It doesn't matter what lib you use, whether it's pcap, tins or packet sniffer 9000. If you want to keep your GUI responsive while using a synchronous library or function, you have to move it to a different thread.

                              Threading in general is a "not-so-easy" task, esp. with limited programming knowledge, but IMO a Worker-Thread is one of the easier approaches and it matches your requirements as well.

                              Read about how it works (in this topic are already plently of links) and be aware of what you really want to do (what function you want to run? what data should be send from where to where?... etc.)


                              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
                              • Pl45m4P Pl45m4

                                @__d4ve__ said in Using QThread , Signal() , Slot() So GUI won't freeze:

                                I'm wondering if there is a better way to accomplish this task maybe using Tins

                                How should this change something? It doesn't matter what lib you use, whether it's pcap, tins or packet sniffer 9000. If you want to keep your GUI responsive while using a synchronous library or function, you have to move it to a different thread.

                                Threading in general is a "not-so-easy" task, esp. with limited programming knowledge, but IMO a Worker-Thread is one of the easier approaches and it matches your requirements as well.

                                Read about how it works (in this topic are already plently of links) and be aware of what you really want to do (what function you want to run? what data should be send from where to where?... etc.)

                                _ Offline
                                _ Offline
                                __d4ve__
                                wrote on last edited by
                                #35

                                @Pl45m4

                                The task is keep GUI responsive , and yes you are right we achieved at this point the threading stuff the issue now have changed into running pcap_loop() which isn't working because it requires static function and I use non-static function

                                Pl45m4P 1 Reply Last reply
                                0
                                • _ __d4ve__

                                  @Pl45m4

                                  The task is keep GUI responsive , and yes you are right we achieved at this point the threading stuff the issue now have changed into running pcap_loop() which isn't working because it requires static function and I use non-static function

                                  Pl45m4P Offline
                                  Pl45m4P Offline
                                  Pl45m4
                                  wrote on last edited by Pl45m4
                                  #36

                                  @__d4ve__ said in Using QThread , Signal() , Slot() So GUI won't freeze:

                                  which isn't working because it requires static function and I use non-static function

                                  This is probably not the reason behind this issue...
                                  I can only repeat what @JonB and others have said...
                                  Look at the lines 55 and 88 and check what's written there or post it here. Because it's a pain to check your linked archieve when you have the code right in front of you. So probably nobody will dig through your whole project to find these two or more lines which will produce your current error.


                                  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
                                  1
                                  • Pl45m4P Pl45m4

                                    @__d4ve__ said in Using QThread , Signal() , Slot() So GUI won't freeze:

                                    which isn't working because it requires static function and I use non-static function

                                    This is probably not the reason behind this issue...
                                    I can only repeat what @JonB and others have said...
                                    Look at the lines 55 and 88 and check what's written there or post it here. Because it's a pain to check your linked archieve when you have the code right in front of you. So probably nobody will dig through your whole project to find these two or more lines which will produce your current error.

                                    _ Offline
                                    _ Offline
                                    __d4ve__
                                    wrote on last edited by
                                    #37

                                    @Pl45m4

                                    line 55 :

                                    emit update_gui(packetInfoQString);
                                    

                                    line 88 :

                                    pcap_loop(handle ,NUM_PACKETS_TO_CAPTURE ,packet_handler , nullptr);
                                    
                                    jsulmJ 1 Reply Last reply
                                    0
                                    • _ __d4ve__

                                      @Pl45m4

                                      line 55 :

                                      emit update_gui(packetInfoQString);
                                      

                                      line 88 :

                                      pcap_loop(handle ,NUM_PACKETS_TO_CAPTURE ,packet_handler , nullptr);
                                      
                                      jsulmJ Offline
                                      jsulmJ Offline
                                      jsulm
                                      Lifetime Qt Champion
                                      wrote on last edited by
                                      #38

                                      @__d4ve__ said in Using QThread , Signal() , Slot() So GUI won't freeze:

                                      emit update_gui(packetInfoQString);

                                      Now, look at the first error message:
                                      "\Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:55: error: C3861: 'update_gui': identifier not found"

                                      It tells you that update_gui is not known. Did you declare update_gui as signal in that class?

                                      https://forum.qt.io/topic/113070/qt-code-of-conduct

                                      _ 1 Reply Last reply
                                      0
                                      • jsulmJ jsulm

                                        @__d4ve__ said in Using QThread , Signal() , Slot() So GUI won't freeze:

                                        emit update_gui(packetInfoQString);

                                        Now, look at the first error message:
                                        "\Project 1 - Network Packet GUI\Packet_Capture_GUI\workerobject.cpp:55: error: C3861: 'update_gui': identifier not found"

                                        It tells you that update_gui is not known. Did you declare update_gui as signal in that class?

                                        _ Offline
                                        _ Offline
                                        __d4ve__
                                        wrote on last edited by
                                        #39

                                        @jsulm

                                        Yes,

                                        signals:
                                            void update_gui(QString packetInfoQString);
                                        };
                                        

                                        The issue is here : pcap_loop got call back function named packet_handle - this function emit update_gui

                                        but the problem here that pcap_loop requires static function , while packet_handle can't be static function

                                        try to run the project that's very short code

                                        JonBJ Pl45m4P 2 Replies Last reply
                                        0
                                        • _ __d4ve__

                                          @jsulm

                                          Yes,

                                          signals:
                                              void update_gui(QString packetInfoQString);
                                          };
                                          

                                          The issue is here : pcap_loop got call back function named packet_handle - this function emit update_gui

                                          but the problem here that pcap_loop requires static function , while packet_handle can't be static function

                                          try to run the project that's very short code

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

                                          @__d4ve__
                                          If you mean that signal update_gui() is a member of MainWindow then you won't be able to call it via

                                          WorkerObject* wo=qobject_cast<WorkerObject*>(user_data);
                                          assert(wo);
                                          wo->update_gui(...);
                                          

                                          You presumably need the signal defined somewhere accessible from WorkerObject and then a slot in MainWindow to receive the signal from the worker object.

                                          Get the principle suggested by @mpergand working.

                                          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