Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Occasionally get "QThread: Destroyed while thread is still running" when running multiple threads
Forum Updated to NodeBB v4.3 + New Features

Occasionally get "QThread: Destroyed while thread is still running" when running multiple threads

Scheduled Pinned Locked Moved Solved Qt for Python
qt for python
25 Posts 4 Posters 7.4k Views 1 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.
  • G gunraidan

    @JonB

    Thank you for your response.

    pokemon_dict = bytes_string was left in by accident.

    I just want to be able to navigate through the api, the same or a similar way as using the traditional Python api method.

    I don't see a template in the link you've provided, and possibly I'm just bad at Googling, but I can't really find anything online. Do you know of any simple templates I can find online? Or, if you could please, show me a quick mock up excerpt if that wouldn't be too much trouble?

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

    @gunraidan
    As I said, you are just missing one step. The bytes_string you get is just a string of the bytes/characters which arrive/come from file. You cannot access the "keys", like pokemon_dict["abilities"], until you have called some JSON library to parse that text as JSON, which is what it is.

    For the JSON you have two choices: Qt has QJson... classes or Python has its own JSON library/classes. You might use either one.

    For the Qt, untested but try:

    from PyQt6 import QtCore
    
    bytes_string = reply.readAll()
    pokemon_dict = QtCore.QJsonDocument.fromJson(bytes_string)
    # you may need next line, not sure:
    # pokemon_dict = pokemon_dict.object()
    print(pokemon_dict["abilities"])
    

    Or you may prefer to do this with the Python JSON classes --- https://docs.python.org/3/library/json.html. I think that would be

    import json
    
    bytes_string = reply.readAll()
    pokemon_dict = json.loads(bytes_string)
    print(pokemon_dict["abilities"])
    
    G 1 Reply Last reply
    0
    • JonBJ JonB

      @gunraidan
      As I said, you are just missing one step. The bytes_string you get is just a string of the bytes/characters which arrive/come from file. You cannot access the "keys", like pokemon_dict["abilities"], until you have called some JSON library to parse that text as JSON, which is what it is.

      For the JSON you have two choices: Qt has QJson... classes or Python has its own JSON library/classes. You might use either one.

      For the Qt, untested but try:

      from PyQt6 import QtCore
      
      bytes_string = reply.readAll()
      pokemon_dict = QtCore.QJsonDocument.fromJson(bytes_string)
      # you may need next line, not sure:
      # pokemon_dict = pokemon_dict.object()
      print(pokemon_dict["abilities"])
      

      Or you may prefer to do this with the Python JSON classes --- https://docs.python.org/3/library/json.html. I think that would be

      import json
      
      bytes_string = reply.readAll()
      pokemon_dict = json.loads(bytes_string)
      print(pokemon_dict["abilities"])
      
      G Offline
      G Offline
      gunraidan
      wrote on last edited by
      #13

      @JonB said in Occasionally get "QThread: Destroyed while thread is still running" when running multiple threads:

      @gunraidan
      As I said, you are just missing one step. The bytes_string you get is just a string of the bytes/characters which arrive/come from file. You cannot access the "keys", like pokemon_dict["abilities"], until you have called some JSON library to parse that text as JSON, which is what it is.

      For the JSON you have two choices: Qt has QJson... classes or Python has its own JSON library/classes. You might use either one.

      For the Qt, untested but try:

      from PyQt6 import QtCore
      
      bytes_string = reply.readAll()
      pokemon_dict = QtCore.QJsonDocument.fromJson(bytes_string)
      # you may need next line, not sure:
      # pokemon_dict = pokemon_dict.object()
      print(pokemon_dict["abilities"])
      

      Or you may prefer to do this with the Python JSON classes --- https://docs.python.org/3/library/json.html. I think that would be

      import json
      
      bytes_string = reply.readAll()
      pokemon_dict = json.loads(bytes_string)
      print(pokemon_dict["abilities"])
      

      Doing the first results in this error:

      qt.tlsbackend.ossl: Failed to load libssl/libcrypto.
      <PyQt6.QtCore.QJsonValue object at 0x00000182BF9CA570>
      

      Doing the second results in this error:

      Traceback (most recent call last):
        File "c:\Users\Nader\OneDrive\Documents\Coding\Python\TestNetwork.py", line 44, in handle_request
          pokemon_dict = json.loads(bytes_string)
        File "C:\Users\Nader\AppData\Local\Programs\Python\Python310\lib\json\__init__.py", line 339, in loads
          raise TypeError(f'the JSON object must be str, bytes or bytearray, '
      TypeError: the JSON object must be str, bytes or bytearray, not QByteArray
      
      JonBJ 1 Reply Last reply
      0
      • G gunraidan

        @JonB said in Occasionally get "QThread: Destroyed while thread is still running" when running multiple threads:

        @gunraidan
        As I said, you are just missing one step. The bytes_string you get is just a string of the bytes/characters which arrive/come from file. You cannot access the "keys", like pokemon_dict["abilities"], until you have called some JSON library to parse that text as JSON, which is what it is.

        For the JSON you have two choices: Qt has QJson... classes or Python has its own JSON library/classes. You might use either one.

        For the Qt, untested but try:

        from PyQt6 import QtCore
        
        bytes_string = reply.readAll()
        pokemon_dict = QtCore.QJsonDocument.fromJson(bytes_string)
        # you may need next line, not sure:
        # pokemon_dict = pokemon_dict.object()
        print(pokemon_dict["abilities"])
        

        Or you may prefer to do this with the Python JSON classes --- https://docs.python.org/3/library/json.html. I think that would be

        import json
        
        bytes_string = reply.readAll()
        pokemon_dict = json.loads(bytes_string)
        print(pokemon_dict["abilities"])
        

        Doing the first results in this error:

        qt.tlsbackend.ossl: Failed to load libssl/libcrypto.
        <PyQt6.QtCore.QJsonValue object at 0x00000182BF9CA570>
        

        Doing the second results in this error:

        Traceback (most recent call last):
          File "c:\Users\Nader\OneDrive\Documents\Coding\Python\TestNetwork.py", line 44, in handle_request
            pokemon_dict = json.loads(bytes_string)
          File "C:\Users\Nader\AppData\Local\Programs\Python\Python310\lib\json\__init__.py", line 339, in loads
            raise TypeError(f'the JSON object must be str, bytes or bytearray, '
        TypeError: the JSON object must be str, bytes or bytearray, not QByteArray
        
        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by JonB
        #14

        @gunraidan said in Occasionally get "QThread: Destroyed while thread is still running" when running multiple threads:

        Doing the first results in this error:

        <PyQt6.QtCore.QJsonValue object at 0x00000182BF9CA570>

        I don't see it being an error. ("qt.tlsbackend.ossl: Failed to load libssl/libcrypto." is over to you, you have had that from the start.) So that actually looks good I think, it has found a QJsonValue in pokemon_dict["abilities"], so it's working.

        TypeError: the JSON object must be str, bytes or bytearray, not QByteArray

        Then you need to convert Qt QByteArray to bytes/bytearray, however you do that from PyQt6.

        G 1 Reply Last reply
        0
        • JonBJ JonB

          @gunraidan said in Occasionally get "QThread: Destroyed while thread is still running" when running multiple threads:

          Doing the first results in this error:

          <PyQt6.QtCore.QJsonValue object at 0x00000182BF9CA570>

          I don't see it being an error. ("qt.tlsbackend.ossl: Failed to load libssl/libcrypto." is over to you, you have had that from the start.) So that actually looks good I think, it has found a QJsonValue in pokemon_dict["abilities"], so it's working.

          TypeError: the JSON object must be str, bytes or bytearray, not QByteArray

          Then you need to convert Qt QByteArray to bytes/bytearray, however you do that from PyQt6.

          G Offline
          G Offline
          gunraidan
          wrote on last edited by
          #15

          @JonB said in Occasionally get "QThread: Destroyed while thread is still running" when running multiple threads:

          @gunraidan said in Occasionally get "QThread: Destroyed while thread is still running" when running multiple threads:

          Doing the first results in this error:

          <PyQt6.QtCore.QJsonValue object at 0x00000182BF9CA570>

          I don't see it being an error. ("qt.tlsbackend.ossl: Failed to load libssl/libcrypto." is over to you, you have had that from the start.) So that actually looks good I think, it has found a QJsonValue in pokemon_dict["abilities"], so it's working.

          TypeError: the JSON object must be str, bytes or bytearray, not QByteArray

          Then you need to convert Qt QByteArray to bytes/bytearray, however you do that from PyQt6.

          When I type the following code:

              def handle_request(self, reply):
                  er = reply.error()
                  
                  if er == QtNetwork.QNetworkReply.NetworkError.NoError:
                      bytes_string = reply.readAll()
                      pokemon_dict = QtCore.QJsonDocument.fromJson(bytes_string)
                      pokemon_dict = pokemon_dict.object()
                      print(pokemon_dict)
          

          This is the output:

          {'abilities': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A570>, 'base_experience': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A5E0>, 'forms': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A650>, 'game_indices': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A6C0>, 'height': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A730>, 'held_items': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A7A0>, 'id': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A810>, 'is_default': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A880>, 'location_area_encounters': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A8F0>, 'moves': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A960>, 'name': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A9D0>, 'order': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0AA40>, 'past_types': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0AAB0>, 'species': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0AB20>, 'sprites': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0AB90>, 'stats': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0AC00>, 'types': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0AC70>, 'weight': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0ACE0>}
          

          So it does successfully import the data. However, unlike the keys, the values in the dictionary aren't strings but more so strange code. Is there a way to have the values be the same text string found in the api like the keys?

          JonBJ 2 Replies Last reply
          0
          • G gunraidan

            @JonB said in Occasionally get "QThread: Destroyed while thread is still running" when running multiple threads:

            @gunraidan said in Occasionally get "QThread: Destroyed while thread is still running" when running multiple threads:

            Doing the first results in this error:

            <PyQt6.QtCore.QJsonValue object at 0x00000182BF9CA570>

            I don't see it being an error. ("qt.tlsbackend.ossl: Failed to load libssl/libcrypto." is over to you, you have had that from the start.) So that actually looks good I think, it has found a QJsonValue in pokemon_dict["abilities"], so it's working.

            TypeError: the JSON object must be str, bytes or bytearray, not QByteArray

            Then you need to convert Qt QByteArray to bytes/bytearray, however you do that from PyQt6.

            When I type the following code:

                def handle_request(self, reply):
                    er = reply.error()
                    
                    if er == QtNetwork.QNetworkReply.NetworkError.NoError:
                        bytes_string = reply.readAll()
                        pokemon_dict = QtCore.QJsonDocument.fromJson(bytes_string)
                        pokemon_dict = pokemon_dict.object()
                        print(pokemon_dict)
            

            This is the output:

            {'abilities': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A570>, 'base_experience': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A5E0>, 'forms': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A650>, 'game_indices': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A6C0>, 'height': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A730>, 'held_items': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A7A0>, 'id': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A810>, 'is_default': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A880>, 'location_area_encounters': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A8F0>, 'moves': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A960>, 'name': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A9D0>, 'order': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0AA40>, 'past_types': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0AAB0>, 'species': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0AB20>, 'sprites': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0AB90>, 'stats': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0AC00>, 'types': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0AC70>, 'weight': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0ACE0>}
            

            So it does successfully import the data. However, unlike the keys, the values in the dictionary aren't strings but more so strange code. Is there a way to have the values be the same text string found in the api like the keys?

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

            @gunraidan
            You have to read the Qt QJson... classes documentation and write the code. Btw did you try to see if your pokemon_dict["abilities"][0]['ability']['name'] works?

            From Python you might be more comfortable getting the json module working. It may integrate more smoothly in Python than the Qt one, if the Qt one doesn't work with your pokemon_dict["abilities"][0]['ability']['name'].

            G 1 Reply Last reply
            0
            • JonBJ JonB

              @gunraidan
              You have to read the Qt QJson... classes documentation and write the code. Btw did you try to see if your pokemon_dict["abilities"][0]['ability']['name'] works?

              From Python you might be more comfortable getting the json module working. It may integrate more smoothly in Python than the Qt one, if the Qt one doesn't work with your pokemon_dict["abilities"][0]['ability']['name'].

              G Offline
              G Offline
              gunraidan
              wrote on last edited by
              #17

              @JonB said in Occasionally get "QThread: Destroyed while thread is still running" when running multiple threads:

              @gunraidan
              You have to read the Qt QJson... classes documentation and write the code. Btw did you try to see if your pokemon_dict["abilities"][0]['ability']['name'] works?

              From Python you might be more comfortable getting the json module working. It may integrate more smoothly in Python than the Qt one, if the Qt one doesn't work with your pokemon_dict["abilities"][0]['ability']['name'].

              This is embarrassing but I just realized I quoted you before without putting my code in.
              It strongly gives the impression I'm not putting in the effort, which I don't think is accurate.

              I came up with the following code:

                  def handle_request(self, reply):
                      er = reply.error()
                      
                      if er == QtNetwork.QNetworkReply.NetworkError.NoError:
              
                          bytes_string = reply.readAll()
                          pokemon_dict = json.loads(bytes_string)
                          x = QByteArray(pokemon_dict["abilities"][0]['ability']['name'])
                          print(x)
              

              In my head the json.loads will load the response into json format and then x will result in that part of the code being transferred to bytes so Python can read it.

              However, I still get the same error:

              Traceback (most recent call last):
                File "c:\Users\Nader\OneDrive\Documents\Coding\Python\TestNetwork.py", line 44, in handle_request
                  bytes_string = json.loads(reply.readAll())
                File "C:\Users\Nader\AppData\Local\Programs\Python\Python310\lib\json\__init__.py", line 339, in loads
                  raise TypeError(f'the JSON object must be str, bytes or bytearray, '
              TypeError: the JSON object must be str, bytes or bytearray, not QByteArray
              

              I have gone to the documentation here, but it lists simply the function and no examples of QJson in use (outside of a saved game load which isn't much like I'm doing.)

              JonBJ 1 Reply Last reply
              0
              • G gunraidan

                @JonB said in Occasionally get "QThread: Destroyed while thread is still running" when running multiple threads:

                @gunraidan
                You have to read the Qt QJson... classes documentation and write the code. Btw did you try to see if your pokemon_dict["abilities"][0]['ability']['name'] works?

                From Python you might be more comfortable getting the json module working. It may integrate more smoothly in Python than the Qt one, if the Qt one doesn't work with your pokemon_dict["abilities"][0]['ability']['name'].

                This is embarrassing but I just realized I quoted you before without putting my code in.
                It strongly gives the impression I'm not putting in the effort, which I don't think is accurate.

                I came up with the following code:

                    def handle_request(self, reply):
                        er = reply.error()
                        
                        if er == QtNetwork.QNetworkReply.NetworkError.NoError:
                
                            bytes_string = reply.readAll()
                            pokemon_dict = json.loads(bytes_string)
                            x = QByteArray(pokemon_dict["abilities"][0]['ability']['name'])
                            print(x)
                

                In my head the json.loads will load the response into json format and then x will result in that part of the code being transferred to bytes so Python can read it.

                However, I still get the same error:

                Traceback (most recent call last):
                  File "c:\Users\Nader\OneDrive\Documents\Coding\Python\TestNetwork.py", line 44, in handle_request
                    bytes_string = json.loads(reply.readAll())
                  File "C:\Users\Nader\AppData\Local\Programs\Python\Python310\lib\json\__init__.py", line 339, in loads
                    raise TypeError(f'the JSON object must be str, bytes or bytearray, '
                TypeError: the JSON object must be str, bytes or bytearray, not QByteArray
                

                I have gone to the documentation here, but it lists simply the function and no examples of QJson in use (outside of a saved game load which isn't much like I'm doing.)

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

                @gunraidan said in Occasionally get "QThread: Destroyed while thread is still running" when running multiple threads:

                I have gone to the documentation here, but it lists simply the function and no examples of QJson in use (outside of a saved game load which isn't much like I'm doing.)

                Well, that's all you get!

                You have attempted to change your code in the light of the error, but unfortunately not the right thing! Please read the message carefully. First:

                File "c:\Users\Nader\OneDrive\Documents\Coding\Python\TestNetwork.py", line 44, in handle_request

                bytes_string = json.loads(reply.readAll())
                

                Since that clearly shows bytes_string = json.loads(reply.readAll()) while you claim your code has pokemon_dict = json.loads(bytes_string), how can you get that error message from the code you show? I can only conclude that is not the code you have to cause that message. Please don't do this, it makes it very frustrating when people try to help and code/messages are not actually what you claim they are.

                Second:

                File "C:\Users\Nader\AppData\Local\Programs\Python\Python310\lib\json_init_.py", line 339, in loads

                raise TypeError(f'the JSON object must be str, bytes or bytearray, '
                

                TypeError: the JSON object must be str, bytes or bytearray, not QByteArray

                Read the error message. It tells you it was in the json.loads(something) call. It tells you it requires the parameter to be "str, bytes or bytearray", but that it is actually "QByteArray" (as returned from readAll()). And it is apparently not prepared to convert for you. Hence I wrote earlier:

                TypeError: the JSON object must be str, bytes or bytearray, not QByteArray

                Then you need to convert Qt QByteArray to bytes/bytearray, however you do that from PyQt6.

                You were supposed to Google to find out how to do that. I don't, I don't use Python. Your putting in x = QByteArray(...) after the json.loads() call is not going to address this, you need to change what you pass to json.loads().

                I will have a go at producing something in next post.....

                1 Reply Last reply
                1
                • G gunraidan

                  @JonB said in Occasionally get "QThread: Destroyed while thread is still running" when running multiple threads:

                  @gunraidan said in Occasionally get "QThread: Destroyed while thread is still running" when running multiple threads:

                  Doing the first results in this error:

                  <PyQt6.QtCore.QJsonValue object at 0x00000182BF9CA570>

                  I don't see it being an error. ("qt.tlsbackend.ossl: Failed to load libssl/libcrypto." is over to you, you have had that from the start.) So that actually looks good I think, it has found a QJsonValue in pokemon_dict["abilities"], so it's working.

                  TypeError: the JSON object must be str, bytes or bytearray, not QByteArray

                  Then you need to convert Qt QByteArray to bytes/bytearray, however you do that from PyQt6.

                  When I type the following code:

                      def handle_request(self, reply):
                          er = reply.error()
                          
                          if er == QtNetwork.QNetworkReply.NetworkError.NoError:
                              bytes_string = reply.readAll()
                              pokemon_dict = QtCore.QJsonDocument.fromJson(bytes_string)
                              pokemon_dict = pokemon_dict.object()
                              print(pokemon_dict)
                  

                  This is the output:

                  {'abilities': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A570>, 'base_experience': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A5E0>, 'forms': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A650>, 'game_indices': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A6C0>, 'height': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A730>, 'held_items': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A7A0>, 'id': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A810>, 'is_default': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A880>, 'location_area_encounters': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A8F0>, 'moves': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A960>, 'name': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0A9D0>, 'order': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0AA40>, 'past_types': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0AAB0>, 'species': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0AB20>, 'sprites': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0AB90>, 'stats': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0AC00>, 'types': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0AC70>, 'weight': <PyQt6.QtCore.QJsonValue object at 0x000001EC6DE0ACE0>}
                  

                  So it does successfully import the data. However, unlike the keys, the values in the dictionary aren't strings but more so strange code. Is there a way to have the values be the same text string found in the api like the keys?

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

                  @gunraidan
                  Here is the code (tested PyQt5) for the two possible approaches:

                  import json
                  
                  from PyQt5 import QtCore
                  
                  if __name__ == '__main__':
                      # I put your sample JSON into a file, since they are not arriving at my serial port
                      f = QtCore.QFile("file.json")
                      if not f.open(QtCore.QIODevice.ReadOnly):
                          raise "Whoops"
                      # following line's `readAll()` returns `QByteArray` type, just like when you read from serial port
                      qbytearray = f.readAll()
                      f.close()
                  
                      # Use `json.loads()` approach:
                      # next line converts Qt `QByteArray` type to Python `bytes` type...
                      pythonbytearray = bytes(qbytearray)
                      # ...so that now it is acceptable to `json.loads(...)`
                      pokemon_dict = json.loads(pythonbytearray)
                      x = pokemon_dict["abilities"][0]['ability']['name']
                      # next line prints `static`, which must be the value there
                      print(x)
                  
                      # Use `QtCore.QJson...` approach:
                      pokemon_dict = QtCore.QJsonDocument.fromJson(qbytearray)
                      x = pokemon_dict["abilities"][0]['ability']['name'].toString()
                      # next line prints `static`, which must be the value there
                      print(x)
                  
                  

                  As you can see, all you had to discover for Python/PyQt json.loads(...) is that you can convert a Qt QByteArray to a Python bytes array via bytes(qByteArrayValue).

                  Use either one of these approaches. The json modules is slightly better integrated into Python than the Qt QJson... classes (e.g. note the QJson expression requires the toString() at the end, but the json one does not), so you may prefer to use the former. On the other hand, while json.loads() requires converting a QByteArray to a bytes, QJsonDocument.fromJson() does not.

                  G 1 Reply Last reply
                  2
                  • JonBJ JonB

                    @gunraidan
                    Here is the code (tested PyQt5) for the two possible approaches:

                    import json
                    
                    from PyQt5 import QtCore
                    
                    if __name__ == '__main__':
                        # I put your sample JSON into a file, since they are not arriving at my serial port
                        f = QtCore.QFile("file.json")
                        if not f.open(QtCore.QIODevice.ReadOnly):
                            raise "Whoops"
                        # following line's `readAll()` returns `QByteArray` type, just like when you read from serial port
                        qbytearray = f.readAll()
                        f.close()
                    
                        # Use `json.loads()` approach:
                        # next line converts Qt `QByteArray` type to Python `bytes` type...
                        pythonbytearray = bytes(qbytearray)
                        # ...so that now it is acceptable to `json.loads(...)`
                        pokemon_dict = json.loads(pythonbytearray)
                        x = pokemon_dict["abilities"][0]['ability']['name']
                        # next line prints `static`, which must be the value there
                        print(x)
                    
                        # Use `QtCore.QJson...` approach:
                        pokemon_dict = QtCore.QJsonDocument.fromJson(qbytearray)
                        x = pokemon_dict["abilities"][0]['ability']['name'].toString()
                        # next line prints `static`, which must be the value there
                        print(x)
                    
                    

                    As you can see, all you had to discover for Python/PyQt json.loads(...) is that you can convert a Qt QByteArray to a Python bytes array via bytes(qByteArrayValue).

                    Use either one of these approaches. The json modules is slightly better integrated into Python than the Qt QJson... classes (e.g. note the QJson expression requires the toString() at the end, but the json one does not), so you may prefer to use the former. On the other hand, while json.loads() requires converting a QByteArray to a bytes, QJsonDocument.fromJson() does not.

                    G Offline
                    G Offline
                    gunraidan
                    wrote on last edited by
                    #20

                    @JonB said in Occasionally get "QThread: Destroyed while thread is still running" when running multiple threads:

                    @gunraidan
                    Here is the code (tested PyQt5) for the two possible approaches:

                    import json
                    
                    from PyQt5 import QtCore
                    
                    if __name__ == '__main__':
                        # I put your sample JSON into a file, since they are not arriving at my serial port
                        f = QtCore.QFile("file.json")
                        if not f.open(QtCore.QIODevice.ReadOnly):
                            raise "Whoops"
                        # following line's `readAll()` returns `QByteArray` type, just like when you read from serial port
                        qbytearray = f.readAll()
                        f.close()
                    
                        # Use `json.loads()` approach:
                        # next line converts Qt `QByteArray` type to Python `bytes` type...
                        pythonbytearray = bytes(qbytearray)
                        # ...so that now it is acceptable to `json.loads(...)`
                        pokemon_dict = json.loads(pythonbytearray)
                        x = pokemon_dict["abilities"][0]['ability']['name']
                        # next line prints `static`, which must be the value there
                        print(x)
                    
                        # Use `QtCore.QJson...` approach:
                        pokemon_dict = QtCore.QJsonDocument.fromJson(qbytearray)
                        x = pokemon_dict["abilities"][0]['ability']['name'].toString()
                        # next line prints `static`, which must be the value there
                        print(x)
                    
                    

                    As you can see, all you had to discover for Python/PyQt json.loads(...) is that you can convert a Qt QByteArray to a Python bytes array via bytes(qByteArrayValue).

                    Use either one of these approaches. The json modules is slightly better integrated into Python than the Qt QJson... classes (e.g. note the QJson expression requires the toString() at the end, but the json one does not), so you may prefer to use the former. On the other hand, while json.loads() requires converting a QByteArray to a bytes, QJsonDocument.fromJson() does not.

                    Thank you.

                    The following code:

                    pokemon_dict = []
                    json2qt = QtCore.QJsonDocument.fromJson
                    
                    class MainWindow(QWidget):  
                        def __init__ (self):
                            super().__init__()
                            self.title = "Window"
                            self.left = 200
                            self.top = 300
                            self.width = 300
                            self.height = 300
                            self.setWindowTitle(self.title)
                            self.setGeometry(self.left, self.top,self.width, self.height)
                    
                            self.start_button()
                            self.show()
                            
                        def start_button(self):
                            self.s_button = QtWidgets.QPushButton(self)
                            self.s_button.setText('Start')
                            self.s_button.clicked.connect(self.site_request)
                            
                        
                        def site_request(self):
                            url = 'https://pokeapi.co/api/v2/pokemon/pikachu'
                            req = QtNetwork.QNetworkRequest(QUrl(url))
                            
                            self.nam = QtNetwork.QNetworkAccessManager()
                            self.nam.finished.connect(self.handle_request)
                            self.nam.get(req)
                            
                        def handle_request(self, reply):
                            er = reply.error()
                            
                            if er == QtNetwork.QNetworkReply.NetworkError.NoError:
                                qbyte = reply.readAll()
                                pokemon_dict = json2qt(qbyte)
                                x = pokemon_dict["abilities"][0]['ability']['name'].toString()
                                print(x)
                            else:
                                print ("Error")
                                print(reply.errorString())
                            
                            
                    if __name__ == '__main__':        
                        app = QApplication(sys.argv) 
                        ex = MainWindow()        
                        code = app.exec()
                        sys.exit(code)
                    

                    Works as it prints the name: "static".

                    Thank you for all your help!

                    One more thing, that you don't have to answer. Do you have any idea what the qt.tlsbackend.ossl: Failed to load libssl/libcrypto. could be? It doesn't effect the program at all and I assume has to do with the api's security not being picked up since it references "ssl"?

                    Doing some research of what "libssl and libcrypto are took me to this page.

                    jsulmJ 1 Reply Last reply
                    0
                    • G gunraidan

                      @JonB said in Occasionally get "QThread: Destroyed while thread is still running" when running multiple threads:

                      @gunraidan
                      Here is the code (tested PyQt5) for the two possible approaches:

                      import json
                      
                      from PyQt5 import QtCore
                      
                      if __name__ == '__main__':
                          # I put your sample JSON into a file, since they are not arriving at my serial port
                          f = QtCore.QFile("file.json")
                          if not f.open(QtCore.QIODevice.ReadOnly):
                              raise "Whoops"
                          # following line's `readAll()` returns `QByteArray` type, just like when you read from serial port
                          qbytearray = f.readAll()
                          f.close()
                      
                          # Use `json.loads()` approach:
                          # next line converts Qt `QByteArray` type to Python `bytes` type...
                          pythonbytearray = bytes(qbytearray)
                          # ...so that now it is acceptable to `json.loads(...)`
                          pokemon_dict = json.loads(pythonbytearray)
                          x = pokemon_dict["abilities"][0]['ability']['name']
                          # next line prints `static`, which must be the value there
                          print(x)
                      
                          # Use `QtCore.QJson...` approach:
                          pokemon_dict = QtCore.QJsonDocument.fromJson(qbytearray)
                          x = pokemon_dict["abilities"][0]['ability']['name'].toString()
                          # next line prints `static`, which must be the value there
                          print(x)
                      
                      

                      As you can see, all you had to discover for Python/PyQt json.loads(...) is that you can convert a Qt QByteArray to a Python bytes array via bytes(qByteArrayValue).

                      Use either one of these approaches. The json modules is slightly better integrated into Python than the Qt QJson... classes (e.g. note the QJson expression requires the toString() at the end, but the json one does not), so you may prefer to use the former. On the other hand, while json.loads() requires converting a QByteArray to a bytes, QJsonDocument.fromJson() does not.

                      Thank you.

                      The following code:

                      pokemon_dict = []
                      json2qt = QtCore.QJsonDocument.fromJson
                      
                      class MainWindow(QWidget):  
                          def __init__ (self):
                              super().__init__()
                              self.title = "Window"
                              self.left = 200
                              self.top = 300
                              self.width = 300
                              self.height = 300
                              self.setWindowTitle(self.title)
                              self.setGeometry(self.left, self.top,self.width, self.height)
                      
                              self.start_button()
                              self.show()
                              
                          def start_button(self):
                              self.s_button = QtWidgets.QPushButton(self)
                              self.s_button.setText('Start')
                              self.s_button.clicked.connect(self.site_request)
                              
                          
                          def site_request(self):
                              url = 'https://pokeapi.co/api/v2/pokemon/pikachu'
                              req = QtNetwork.QNetworkRequest(QUrl(url))
                              
                              self.nam = QtNetwork.QNetworkAccessManager()
                              self.nam.finished.connect(self.handle_request)
                              self.nam.get(req)
                              
                          def handle_request(self, reply):
                              er = reply.error()
                              
                              if er == QtNetwork.QNetworkReply.NetworkError.NoError:
                                  qbyte = reply.readAll()
                                  pokemon_dict = json2qt(qbyte)
                                  x = pokemon_dict["abilities"][0]['ability']['name'].toString()
                                  print(x)
                              else:
                                  print ("Error")
                                  print(reply.errorString())
                              
                              
                      if __name__ == '__main__':        
                          app = QApplication(sys.argv) 
                          ex = MainWindow()        
                          code = app.exec()
                          sys.exit(code)
                      

                      Works as it prints the name: "static".

                      Thank you for all your help!

                      One more thing, that you don't have to answer. Do you have any idea what the qt.tlsbackend.ossl: Failed to load libssl/libcrypto. could be? It doesn't effect the program at all and I assume has to do with the api's security not being picked up since it references "ssl"?

                      Doing some research of what "libssl and libcrypto are took me to this page.

                      jsulmJ Online
                      jsulmJ Online
                      jsulm
                      Lifetime Qt Champion
                      wrote on last edited by
                      #21

                      @gunraidan said in Occasionally get "QThread: Destroyed while thread is still running" when running multiple threads:

                      libssl/libcrypto

                      It's the OpenSSL library which is needed if you want to access https URLs.

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

                      G 1 Reply Last reply
                      1
                      • jsulmJ jsulm

                        @gunraidan said in Occasionally get "QThread: Destroyed while thread is still running" when running multiple threads:

                        libssl/libcrypto

                        It's the OpenSSL library which is needed if you want to access https URLs.

                        G Offline
                        G Offline
                        gunraidan
                        wrote on last edited by
                        #22

                        @jsulm said in Occasionally get "QThread: Destroyed while thread is still running" when running multiple threads:

                        OpenSSL library

                        I followed the directions here to go to this site and download the installer for Windows.

                        I still get the error though. :(

                        jsulmJ 1 Reply Last reply
                        0
                        • G gunraidan

                          @jsulm said in Occasionally get "QThread: Destroyed while thread is still running" when running multiple threads:

                          OpenSSL library

                          I followed the directions here to go to this site and download the installer for Windows.

                          I still get the error though. :(

                          jsulmJ Online
                          jsulmJ Online
                          jsulm
                          Lifetime Qt Champion
                          wrote on last edited by
                          #23

                          @gunraidan You should rather install OpenSSL through Qt installer/maintenance tool. See https://stackoverflow.com/questions/68624474/how-to-deploy-qt-application-with-openssl

                          Also, this is only an issue if you want to access HTTPS URLs. For HTTP you do not need OpenSSL.

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

                          1 Reply Last reply
                          0
                          • G Offline
                            G Offline
                            gunraidan
                            wrote on last edited by
                            #24

                            I'm not sure if I should make a new thread or not, so I'll just post this here.

                            I can't get self.d_name to print after the api function has been called:

                            from PyQt6 import QtNetwork
                            from PyQt6 import QtCore
                            from PyQt6.QtCore import QUrl
                            from PyQt6.QtGui import*
                            from PyQt6 import QtWidgets
                            from PyQt6.QtWidgets import*
                            import sys
                            
                            json2qt = QtCore.QJsonDocument.fromJson
                            
                            class MainWindow(QWidget):  
                                def __init__ (self):
                                    super().__init__()
                                    self.title = "Window"
                                    self.left = 200
                                    self.top = 300
                                    self.width = 300
                                    self.height = 300
                                    self.setWindowTitle(self.title)
                                    self.setGeometry(self.left, self.top,self.width, self.height)
                                    self.start_button()
                                    self.show()
                                    
                                def start_button(self):
                                    self.s_button = QtWidgets.QPushButton(self)
                                    self.s_button.setText('Start')
                                    self.s_button.clicked.connect(self.site_request)
                                    
                                
                                def site_request(self):
                                    url = 'https://pokeapi.co/api/v2/pokemon/pikachu'
                                    req = QtNetwork.QNetworkRequest(QUrl(url))
                                    
                                    self.nam = QtNetwork.QNetworkAccessManager()
                                    self.nam.finished.connect(self.handle_request)
                                    self.nam.get(req)
                                    
                                def handle_request(self, reply):
                                    er = reply.error()
                                    if er == QtNetwork.QNetworkReply.NetworkError.NoError:
                                        qbyte = reply.readAll()
                                        pokemon_dict = json2qt(qbyte)
                                        self.d_name = pokemon_dict["abilities"][0]['ability']['name'].toString()
                                    else:
                                        print ("Error")
                                        print(reply.errorString())
                                        
                                def get_all(self):
                                    self.site_request()
                                    print(self.d_name)
                            
                            if __name__ == '__main__':        
                                app = QApplication(sys.argv) 
                                ex = MainWindow()        
                                code = app.exec()
                                sys.exit(code)
                            

                            However, when I put self.d_name to print here:

                              def handle_request(self, reply):
                                    er = reply.error()
                                    if er == QtNetwork.QNetworkReply.NetworkError.NoError:
                                        qbyte = reply.readAll()
                                        pokemon_dict = json2qt(qbyte)
                                        self.d_name = pokemon_dict["abilities"][0]['ability']['name'].toString()
                                        print (self.d_name)
                                    else:
                                        print ("Error")
                                        print(reply.errorString())
                            

                            It prints out fine.

                            It should print out either way, it's a "self variable".

                            Anyone know what I'm doing wrong?

                            JonBJ 1 Reply Last reply
                            0
                            • G gunraidan

                              I'm not sure if I should make a new thread or not, so I'll just post this here.

                              I can't get self.d_name to print after the api function has been called:

                              from PyQt6 import QtNetwork
                              from PyQt6 import QtCore
                              from PyQt6.QtCore import QUrl
                              from PyQt6.QtGui import*
                              from PyQt6 import QtWidgets
                              from PyQt6.QtWidgets import*
                              import sys
                              
                              json2qt = QtCore.QJsonDocument.fromJson
                              
                              class MainWindow(QWidget):  
                                  def __init__ (self):
                                      super().__init__()
                                      self.title = "Window"
                                      self.left = 200
                                      self.top = 300
                                      self.width = 300
                                      self.height = 300
                                      self.setWindowTitle(self.title)
                                      self.setGeometry(self.left, self.top,self.width, self.height)
                                      self.start_button()
                                      self.show()
                                      
                                  def start_button(self):
                                      self.s_button = QtWidgets.QPushButton(self)
                                      self.s_button.setText('Start')
                                      self.s_button.clicked.connect(self.site_request)
                                      
                                  
                                  def site_request(self):
                                      url = 'https://pokeapi.co/api/v2/pokemon/pikachu'
                                      req = QtNetwork.QNetworkRequest(QUrl(url))
                                      
                                      self.nam = QtNetwork.QNetworkAccessManager()
                                      self.nam.finished.connect(self.handle_request)
                                      self.nam.get(req)
                                      
                                  def handle_request(self, reply):
                                      er = reply.error()
                                      if er == QtNetwork.QNetworkReply.NetworkError.NoError:
                                          qbyte = reply.readAll()
                                          pokemon_dict = json2qt(qbyte)
                                          self.d_name = pokemon_dict["abilities"][0]['ability']['name'].toString()
                                      else:
                                          print ("Error")
                                          print(reply.errorString())
                                          
                                  def get_all(self):
                                      self.site_request()
                                      print(self.d_name)
                              
                              if __name__ == '__main__':        
                                  app = QApplication(sys.argv) 
                                  ex = MainWindow()        
                                  code = app.exec()
                                  sys.exit(code)
                              

                              However, when I put self.d_name to print here:

                                def handle_request(self, reply):
                                      er = reply.error()
                                      if er == QtNetwork.QNetworkReply.NetworkError.NoError:
                                          qbyte = reply.readAll()
                                          pokemon_dict = json2qt(qbyte)
                                          self.d_name = pokemon_dict["abilities"][0]['ability']['name'].toString()
                                          print (self.d_name)
                                      else:
                                          print ("Error")
                                          print(reply.errorString())
                              

                              It prints out fine.

                              It should print out either way, it's a "self variable".

                              Anyone know what I'm doing wrong?

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

                              @gunraidan
                              It won't be about self (that bit is fine), it will be about when you try to print the value.

                              Firstly, you have print(self.d_name) inside a method get_all(). But since your code never actually calls get_all()....

                              Even if you did call it. site_request()calls self.nam.get(req). But QNetworkAccessManager.get() only initiates a GET request. It does not wait for it to complete and return. Only when finished signal is received and handle_request() is called does self.d_name = ... get executed. That happens asynchronously at a later time. So trying to access it immediately after calling site_request() is too early.

                              1 Reply Last reply
                              1

                              • Login

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