[Qt Anfänger] selbstgeschriebene Klasse / Instanzen davon in MainWindow erzeugen & nutzen



  • Hallo,

    ich versuche mal, dass Problem kurz per Code darzustellen:

    //mainwindow.cpp
    void MainWindow::Battle()
    {
        character Spieler("C:\\Users\\Tobias\\qt\\rpg01\\data\\characters\\spieler.ini", 1);
    }
    
    void MainWindow::Button1Click()
    {
        ui->listWidget->addItem(Spieler.name + "greift Gegner 1 an.");
    }
    

    Fehler ist jetzt natürlich, dass "Spieler" in "Button1Click()" NICHT bekannt ist, da in "Battle()" erzeugt. Wie bekomme ich es hin, dass character-Instanzen global bekannt sind? Ich möchte allerdings die Instanzen unbedingt in einer Funktion von MainWindow erzeugen und nicht direkt in direkt mainwindow.cpp.
    Kann mir jemand einen Tip geben? Vermutlich ist es mal wieder etwas ganz einfaches, grundlegendes 🙄
    Vielen Dank im Voraus!



  • thuering schrieb:

    Ich möchte allerdings die Instanzen unbedingt in einer Funktion von MainWindow erzeugen und nicht direkt in direkt mainwindow.cpp.

    Hat das einen bestimmten Grund?



  • Nur Funktionen kann ich immer wieder aufrufen. Und nur in MainWindow steht mir "ui" zur Verfügung.



  • Ja das stimmt schon, aber du könntest doch in der Klassenbeschreibung
    folgendes machen :

    class MainWindow : public QMainWindow
    {
      public:
      void Battle();
      void Button1Click();
       ....
      private:
      [b]Character* myCharacter_;[/b]
    };
    
    void MainWindow::Battle()
    {
        myCharacter_ = new Character("C:\\Users\\Tobias\\qt\\rpg01\\data\\characters\\spieler.ini", 1);
    }
    
    void MainWindow::Button1Click()
    {
        ui->listWidget->addItem(myCharacter_->name + "greift Gegner 1 an.");
    }
    

    Das fett markierte verstehe ich nicht warum das nicht so machen möchtest,
    wenn du später zwischen mehreren Spieler unterscheiden willst dann kannst du das ja innerhalb von Battle machen.



  • Nein, dass funktioniert so leider nicht. Mit "character" werden auch die (vielen) Gegner erstellt und dass soll dynamisch passieren. Diese ganzen "character" Instanzen sollen später auch noch in einen Vector gesteckt werden oder auch gleich im Vector erzeugt werden.

    P.S.: Die Ausgabe, die ich mit deiner Methode habe, sieht komischerweise so aus:
    http://www.abload.de/image.php?img=name_ausgabejkw2.jpg
    P.P.S.: In der Listbox sollte eigentlich "Arthus greift Gegner 1 an." stehen.



  • @phcn.fraggle

    myCharacter_ = new Character("C:\\Users\\Tobias\\qt\\rpg01\\data\\characters\\spieler.ini", 1);

    Warum willst Du, das er von einer stack klasse auf eine Heap klasse switcht ???
    Hasst du was gegen effiziente C++ Programmierung ? ^^

    @Thuering

    Wie bekomme ich es hin, dass character-Instanzen global bekannt sind?

    In dem du sich in Globale Objecte packst ...
    Aber designtechnisch ist das sehr fragwuerdig !!!
    Globale Objecte sollte man meiden. Selbst als Perfekte Singleton Implementierung 🙂
    Es gibt nur wenige "Anwendungsfälle" wo globale Instanzen Sinn machen, und dann sind die Logischen Dinge die dahinter stehen auch immer globaler Natur.

    Als Beispiele werden immer "Drucker", "Logging-Instanz", Applikation-Instanz genannt.
    Aber selbst in diesen Anwendungsfällen kann man die Teile lokal machen, aber im gegenzug handelt man sich meist "nur" längere Paramterlisten ein.

    Wenn dein MainWindow die eigentliche/ logiche Hauptinstanz deines Progs ist ... macht es sinn deine charakter an nem Manager auch dran zu hängen.

    Der UI designer und der moccer sollen/dürfen von dem natuerlich nix wissen. Aber in deinen Slots hasst du natuerlich alles wieder parat, was du in deiner eigenen QMainWIndow Ableitung instanzieierst ....

    Besser:

    class MainWindow : public QMainWindow
    {
      public:
      void Battle();
      void Button1Click();
       ....
      private:
      Character myCharacter;
      Character myOpponent;
    };
    
    void MainWindow::Battle()
    {
        //Das ist noch arg ausbau und verbesserungswürdig !
    
        myCharacter.setIrgendwas("C:\\Users\\Tobias\\qt\\rpg01\\data\\characters\\spieler.ini", 1);
        myOpponent.setIrgendwas("C:\\Users\\Tobias\\qt\\rpg01\\data\\characters\\Opponents.ini", 5);
    
    }
    
    void MainWindow::Button1Click()
    {
        QString strMessage(tr("%1 greift %2 an.")).arg(myCharacter.name(),myOpponent.name());
        ui->listWidget->addItem(strMessage);
    }
    

    Ciao ...



  • @RHBaum
    Hat keinen Grund, hab nur schnell ein Beispiel hingeschrieben nur um zu wissen
    warum er das nicht als Klassen-Attribut haben möchte 😉

    Allerdings wird das was du hast auch nicht das sein was er wollte ( dein Vorschlag ist ja im Prinzip das selbe, nur das dein Objekt auf dem Stack liegt )

    In dem du sich in Globale Objecte packst ...
    Aber designtechnisch ist das sehr fragwuerdig !!!

    Wollte ich auch vorschlagen aber wie du schon sagst, eher fragwürdig.

    @thuering

    Dann versuche doch mal dein Programm zu debuggen um festzustellen weshalb der Name nicht angezeigt wird.



  • Vielen Dank für eure Hilfe und die Vorschläge.
    Ich habe letztendlich auch den Tip bekommen, std::vector<character*> characters; in MainWindow private: zu schreiben. Das funktioniert gut.


Log in to reply