Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. German
  4. QMap im globalen Bereich
Forum Updated to NodeBB v4.3 + New Features

QMap im globalen Bereich

Scheduled Pinned Locked Moved Solved German
13 Posts 3 Posters 2.8k 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.
  • K koahnig

    @Throndar

    Beim Ausdruck "Gloabaler Speicher" bekommen einige schon Schnappatmung. Vorteil ist natürlich, dass jeder direkt darauf zugreifen kann. Der Nachteil ist aber auch dass jeder direkt unkontrolliert darauf zugreifen. Dies ist nicht unbedingt reentrant und kann zu seltsamen Phänomenen führen.

    Ich würde die Liste zumindest nur als statisches Member in eine Klasse packen. Ueber statische Routinen kannst du dann auch von überall her zugreifen, aber du hast wenigstens eine Kontrolle wie zugegriffen wird.

    T Offline
    T Offline
    Throndar
    wrote on last edited by Throndar
    #4

    Hallo @koahnig ,

    danke für deine Hilfe und static ist eigentlich genau das was Sinn ergibt für meine Clientliste.

    Ich habe gerade mal etwas gesucht, mit "static" bleibt ja eine Variable erhalten auch wenn die Funktion die sie erstellt beendet ist, nur waren die Beispiele dich ich im Netz gefunden haben bisher so aufgebaut das über eine static int zum Beispiel ein Zähler für die Anzahl der Aufrufe einer Funktion gebaut wurde.

    Meine erste Idee einfach bei der Erstellung der QMap ein "static" davor zu setzen um es als statisch zu kennzeichnen war nicht erfolgreich.

    static QMap<QString, MovieClient*> movieClients;
    
    lieferte:
    udpreceiver.obj:-1: Fehler: LNK2001: unresolved external symbol "public: static class QMap<class QString,class MovieClient *> UdpReceiver::movieClients" (?movieClients@UdpReceiver@@2V?$QMap@VQString@@PEAVMovieClient@@@@A)
    

    womit ich leider nichts anfangen konnte.

    Da du "statischen Routinen" erwähnt hast hatte ich gehofft das mir der Ansatz plus Google mir weiter hilft was leider nicht der Fall war. Kannst du mir vielleicht sagen was du mit den statischen Routinen meintest?

    K 1 Reply Last reply
    0
    • aha_1980A aha_1980

      Schnappatmung

      Der war gut :)

      Aber ehrlich, globale Variablen in C++ sind nicht ganz ungefährlich. Zum Beispiel wird int globalInt = 0 keine großen Problem verursachen, da er beim Programmstart initialisiert wird. Dagegen muss für QMap<QString, MovieClient*> movieClients; ein Klassenkonstruktur aufgerufen werden; wann das passiert ist in C++ undefiniert. Es kann also passieren, dass Du auf die Map zugreifst bevor sie initialisiert ist und das gibt einen schönen Crash :)

      Ehrlicherweise muss ich sagen, dass es auch für dieses Problem in Qt eine Lösung gibt, und zwar Q_GLOBAL_STATIC. Besser ist aber wie von @koahnig vorgeschlagen, statische Membervariablen zu verwenden.

      Grüße

      T Offline
      T Offline
      Throndar
      wrote on last edited by
      #5

      Hallo @aha_1980

      ich habe versucht mich in die Q_GLOBAL_STATIC und Q_GLOBAL_STATIC_WITH_ARGS einzulesen, und bin jetzt gerade etwas verwirrt. Nach dem was ich gelesen habe erzeugen die beiden ein Object des übergebenen Typs (mit bzw ohne Argumente).

      Für eine QMap wie ich sie verwenden wollte (da ich mehrere gleiche Objekte erstellen will) scheine ich die nicht nutzen zu können, oder habe ich das falsch verstanden?

      1 Reply Last reply
      0
      • T Throndar

        Hallo @koahnig ,

        danke für deine Hilfe und static ist eigentlich genau das was Sinn ergibt für meine Clientliste.

        Ich habe gerade mal etwas gesucht, mit "static" bleibt ja eine Variable erhalten auch wenn die Funktion die sie erstellt beendet ist, nur waren die Beispiele dich ich im Netz gefunden haben bisher so aufgebaut das über eine static int zum Beispiel ein Zähler für die Anzahl der Aufrufe einer Funktion gebaut wurde.

        Meine erste Idee einfach bei der Erstellung der QMap ein "static" davor zu setzen um es als statisch zu kennzeichnen war nicht erfolgreich.

        static QMap<QString, MovieClient*> movieClients;
        
        lieferte:
        udpreceiver.obj:-1: Fehler: LNK2001: unresolved external symbol "public: static class QMap<class QString,class MovieClient *> UdpReceiver::movieClients" (?movieClients@UdpReceiver@@2V?$QMap@VQString@@PEAVMovieClient@@@@A)
        

        womit ich leider nichts anfangen konnte.

        Da du "statischen Routinen" erwähnt hast hatte ich gehofft das mir der Ansatz plus Google mir weiter hilft was leider nicht der Fall war. Kannst du mir vielleicht sagen was du mit den statischen Routinen meintest?

        K Offline
        K Offline
        koahnig
        wrote on last edited by
        #6

        @Throndar said in QMap im globalen Bereich:

        Hallo @koahnig ,

        danke für deine Hilfe und static ist eigentlich genau das was Sinn ergibt für meine Clientliste.

        Ich habe gerade mal etwas gesucht, mit "static" bleibt ja eine Variable erhalten auch wenn die Funktion die sie erstellt beendet ist, nur waren die Beispiele dich ich im Netz gefunden haben bisher so aufgebaut das über eine static int zum Beispiel ein Zähler für die Anzahl der Aufrufe einer Funktion gebaut wurde.

        Meine erste Idee einfach bei der Erstellung der QMap ein "static" davor zu setzen um es als statisch zu kennzeichnen war nicht erfolgreich.

        static QMap<QString, MovieClient*> movieClients;
        
        lieferte:
        udpreceiver.obj:-1: Fehler: LNK2001: unresolved external symbol "public: static class QMap<class QString,class MovieClient *> UdpReceiver::movieClients" (?movieClients@UdpReceiver@@2V?$QMap@VQString@@PEAVMovieClient@@@@A)
        

        womit ich leider nichts anfangen konnte.

        Da du "statischen Routinen" erwähnt hast hatte ich gehofft das mir der Ansatz plus Google mir weiter hilft was leider nicht der Fall war. Kannst du mir vielleicht sagen was du mit den statischen Routinen meintest?

        So sollte es gehen:

        #ifndef MYCLASS_H
        #define MYCLASS_H
        
        #include <QMap>
        #include <QString>
        
        class MyClass
        {
            static int MyStaticInt;
            static QMap < QString, QString *> MyStaticMap;
        public:
            MyClass();
        };
        
        #endif // MYCLASS_H
        
        #include "MyClass.h"
        
        int MyClass::MyStaticInt = 0;
        
        QMap<QString, QString*> MyClass::MyStaticMap;
        
        MyClass::MyClass()
        {
        }
        

        Vote the answer(s) that helped you to solve your issue(s)

        1 Reply Last reply
        1
        • K Offline
          K Offline
          koahnig
          wrote on last edited by
          #7

          Oder mit Q_GLOBAL_STATIC:

          #include "MyClass.h"
          
          #include <QSet>
          
          int MyClass::MyStaticInt = 0;
          
          QMap<QString, QString*> MyClass::MyStaticMap;
          
          Q_GLOBAL_STATIC (int, MyTotalGlobalInt);
          Q_GLOBAL_STATIC (QSet<QString>, MyTotalGlobalQSet);
          
          typedef QMap<QString,QString> MyMapT;
          Q_GLOBAL_STATIC(MyMapT,MyTotalGlobalQMap);
          
          MyClass::MyClass()
          {
          
          }
          

          So lässt es sich übersetzen.Musst aber einmal schauen, ob es da Nebeneffekte gibt.

          Wie geschrieben, die static als Member ist besser.

          Vote the answer(s) that helped you to solve your issue(s)

          T 1 Reply Last reply
          2
          • K koahnig

            Oder mit Q_GLOBAL_STATIC:

            #include "MyClass.h"
            
            #include <QSet>
            
            int MyClass::MyStaticInt = 0;
            
            QMap<QString, QString*> MyClass::MyStaticMap;
            
            Q_GLOBAL_STATIC (int, MyTotalGlobalInt);
            Q_GLOBAL_STATIC (QSet<QString>, MyTotalGlobalQSet);
            
            typedef QMap<QString,QString> MyMapT;
            Q_GLOBAL_STATIC(MyMapT,MyTotalGlobalQMap);
            
            MyClass::MyClass()
            {
            
            }
            

            So lässt es sich übersetzen.Musst aber einmal schauen, ob es da Nebeneffekte gibt.

            Wie geschrieben, die static als Member ist besser.

            T Offline
            T Offline
            Throndar
            wrote on last edited by Throndar
            #8

            Hallo @koahnig ,

            wow vielen vielen Dank!

            Mit den Beispielen konnte ich jetzt endlich den Aufbau nachvollziehen wie man static verwenden muss.

            Jetzt ist nur noch ein Problem von mir offen an dem ich fest hänge. Ich kann jetzt meine Werte programmweit erreichen, nur komme ich aus dem QML Context nicht ran.

            Ich habe ein Objekt der Klasse "UdpReceiver" in der Main erstellt und per

            engine.rootContext()->setContextProperty("UdpReceiver", &uReceiver);
            

            im QML verfügbar gemacht. Jetzt kann ich aus dem QML auf die per Q_INVOKEABLE gekennzeichneten Funktionen zugreifen.

            Die Klasse selbst habe ich (nachdem ich Konstruktor, Destruktor und CopyKontruktor erstellt habe) per

            Q_DECLARE_METATYPE(UdpReceiver)
            

            im MOC bekannt gemacht. Das gleiche habe ich mit der Klasse "MovieClients" gemacht.

            Bei dem Versuch jetzt per:

            Q_PROPERTY(QMap<QString, MovieClient*> movieClientList MEMBER movieClients)
            

            die QMap für QML nutzbar zu machen bekomme ich als Meldung

            
            Lexical or Preprocessor Issue
             
            17:30: error: too many arguments provided to function-like macro invocation
            qobjectdefs.h:62:9: note: macro 'Q_PROPERTY' defined here
            

            Ich kann das Programm zwar starten und bekomme auch im QML Context die "movieClientList" zur auswahl, aber scheinbar komplett ohne Ziel (per Console log liefert ein typeof "undefined".

            Mache ich da einen Fehler beim Versuch die QMap aus dem QML erreichbar zu machen oder ist mein Ansatz komplett falsch an der Stelle?

            1 Reply Last reply
            0
            • T Offline
              T Offline
              Throndar
              wrote on last edited by
              #9

              Nachtrag:

              Das Problem mit den "to many arguments" scheint vom Komma in QMap zu kommen.

              Ich habe darauf hin versucht per

              typedef QMap<QString, MovieClient*> movies;
              

              das Komma zu umgehen. Das klappt soweit, nur meckert er jetzt

              QMetaProperty::read: Unable to handle unregistered datatype 'movies' for property 'UdpReceiver::movieClientList'
              
              K 1 Reply Last reply
              0
              • T Throndar

                Nachtrag:

                Das Problem mit den "to many arguments" scheint vom Komma in QMap zu kommen.

                Ich habe darauf hin versucht per

                typedef QMap<QString, MovieClient*> movies;
                

                das Komma zu umgehen. Das klappt soweit, nur meckert er jetzt

                QMetaProperty::read: Unable to handle unregistered datatype 'movies' for property 'UdpReceiver::movieClientList'
                
                K Offline
                K Offline
                koahnig
                wrote on last edited by
                #10

                @Throndar

                Die Makros haben ein Problem mit dem Komma, das hast du richtig erkannt.

                Da musst du wohl noch qRegisterMetaType durchführen. Das zweite Beispiel sieht doch recht ähnlich mit deinem Fall:

                typedef QString CustomString;
                qRegisterMetaType<CustomString>("CustomString");
                

                Da muss ich auch gerade durchhangeln. ;)

                Vote the answer(s) that helped you to solve your issue(s)

                T 1 Reply Last reply
                2
                • K koahnig

                  @Throndar

                  Die Makros haben ein Problem mit dem Komma, das hast du richtig erkannt.

                  Da musst du wohl noch qRegisterMetaType durchführen. Das zweite Beispiel sieht doch recht ähnlich mit deinem Fall:

                  typedef QString CustomString;
                  qRegisterMetaType<CustomString>("CustomString");
                  

                  Da muss ich auch gerade durchhangeln. ;)

                  T Offline
                  T Offline
                  Throndar
                  wrote on last edited by Throndar
                  #11

                  Hallo @koahnig

                  super, das mit dem qRegisterMetaType hat mich schonmal einen riesigen Schritt weiter gebracht.

                  Ich habe jetzt sowohl die Klasse die ich erstellt habe als auch die QMap die Key und die Objekte (MovieClients) der eigenen Klassen enthält damit registriert und komme schonmal soweit das ich per

                  console.log(UdpReceiver.movieClientList)
                  

                  ein

                  qml: QVariant(QMap<QString,MovieClient*>)
                  

                  zurück erhalte.

                  (unter UdpReceiver ist der Name des Objekt unter dem ich es im QML Context verfügbar gemacht, movieClientList ist die Property unter der ich die QMap<QString, MovieClient*> bekannt gemacht habe).

                  Ich scheine also schon bis zum Objekt zu kommen in dem die QMap liegt, nur funktioniert der "normale" Zugriff auf die Werte scheinbar nicht. Im C++ Context würde ich jetzt ja beispielsweise mit

                  movieClients["192.168.100.94"]->name();
                  

                  auf die Daten die im MovieClient Objekt mit dem Key "192.168.100.94" an Eigenschat "name" liegen kommen, im QML kommt aber schon bei

                  console.log(UdpReceiver.movieClientList["192.168.100.94"])
                  oder
                  console.log(UdpReceiver.movieClientList.value("192.168.100.94"))
                  

                  Als Antwort ein:

                  undefined. (erste Anfrage)
                  bzw
                  TypeError: Property 'value' of object QVariant(QMap<QString,MovieClient*>) is not a function

                  zurück.

                  Ich gehe jetzt davon aus das der Fehler darin liegt das die QMap in einer QVariant liegt, aber wie kann ich auf den Inhalt einer QVariant zugreifen an der Stelle?

                  K 1 Reply Last reply
                  0
                  • T Throndar

                    Hallo @koahnig

                    super, das mit dem qRegisterMetaType hat mich schonmal einen riesigen Schritt weiter gebracht.

                    Ich habe jetzt sowohl die Klasse die ich erstellt habe als auch die QMap die Key und die Objekte (MovieClients) der eigenen Klassen enthält damit registriert und komme schonmal soweit das ich per

                    console.log(UdpReceiver.movieClientList)
                    

                    ein

                    qml: QVariant(QMap<QString,MovieClient*>)
                    

                    zurück erhalte.

                    (unter UdpReceiver ist der Name des Objekt unter dem ich es im QML Context verfügbar gemacht, movieClientList ist die Property unter der ich die QMap<QString, MovieClient*> bekannt gemacht habe).

                    Ich scheine also schon bis zum Objekt zu kommen in dem die QMap liegt, nur funktioniert der "normale" Zugriff auf die Werte scheinbar nicht. Im C++ Context würde ich jetzt ja beispielsweise mit

                    movieClients["192.168.100.94"]->name();
                    

                    auf die Daten die im MovieClient Objekt mit dem Key "192.168.100.94" an Eigenschat "name" liegen kommen, im QML kommt aber schon bei

                    console.log(UdpReceiver.movieClientList["192.168.100.94"])
                    oder
                    console.log(UdpReceiver.movieClientList.value("192.168.100.94"))
                    

                    Als Antwort ein:

                    undefined. (erste Anfrage)
                    bzw
                    TypeError: Property 'value' of object QVariant(QMap<QString,MovieClient*>) is not a function

                    zurück.

                    Ich gehe jetzt davon aus das der Fehler darin liegt das die QMap in einer QVariant liegt, aber wie kann ich auf den Inhalt einer QVariant zugreifen an der Stelle?

                    K Offline
                    K Offline
                    koahnig
                    wrote on last edited by
                    #12

                    @Throndar

                    Da muss ich passen. Mit QML habe ich selbst noch keine richtige Erafhrung.

                    Vote the answer(s) that helped you to solve your issue(s)

                    T 1 Reply Last reply
                    1
                    • K koahnig

                      @Throndar

                      Da muss ich passen. Mit QML habe ich selbst noch keine richtige Erafhrung.

                      T Offline
                      T Offline
                      Throndar
                      wrote on last edited by
                      #13

                      @koahnig

                      trotzdem Danke für deine Mühe, immerhin bin ich jetzt schon soweit das ich das was ich habe im QML habe... wenn auch eingepackt in einer QVariant aber schon mal überhaupt da.

                      Vielleicht hat ja noch jemand anders einen Tipp für mich :)

                      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