2016-06-08 8 views
0

Ich habe eine GUI namens UINode und ich möchte ein Duplikat erstellen und nur ein paar Dinge ändern. Das Projekt besteht aus 3 grundlegenden Threads. PingThread, RosThread und der GuiThread. Ich habe versucht, den Projektordner zu kopieren und in UINode2 umzubenennen, aber es gibt mir Fehler, wenn ich versuche, ihn mit catkin_make zu kompilieren. Ich bin mir ziemlich sicher, dass dies Fehler sind, die durch die identischen Header verursacht werden.C++ Qt So erstellen Sie eine Duplikate einer GUI mit kleinen Änderungen

Fehler:

CMakeFiles/drone_gui2.dir/src/UINode/moc_tum_ardrone_gui.cxx.o:moc_tum_ardrone_gui.cxx:(.text+0x0): first defined here CMakeFiles/drone_gui2.dir/src/UINode2/moc_tum_ardrone_gui.cxx.o:(.rodata+0x100): multiple definition of `tum_ardrone_gui::staticMetaObject' CMakeFiles/drone_gui2.dir/src/UINode/moc_tum_ardrone_gui.cxx.o:(.rodata+0x100): first defined here CMakeFiles/drone_gui2.dir/src/UINode2/moc_tum_ardrone_gui.cxx.o: In function `tum_ardrone_gui::qt_metacast(char const*)': moc_tum_ardrone_gui.cxx:(.text+0x20): multiple definition of `tum_ardrone_gui::qt_metacast(char const*)' CMakeFiles/drone_gui2.dir/src/UINode/moc_tum_ardrone_gui.cxx.o:moc_tum_ardrone_gui.cxx:(.text+0x20): first defined here CMakeFiles/drone_gui2.dir/src/UINode2/moc_tum_ardrone_gui.cxx.o: In function `tum_ardrone_gui::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)': moc_tum_ardrone_gui.cxx:(.text+0x70): multiple definition of `tum_ardrone_gui::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)' CMakeFiles/drone_gui2.dir/src/UINode/moc_tum_ardrone_gui.cxx.o:moc_tum_ardrone_gui.cxx:(.text+0x70): first defined here CMakeFiles/drone_gui2.dir/src/UINode2/moc_tum_ardrone_gui.cxx.o: In function `tum_ardrone_gui::qt_metacall(QMetaObject::Call, int, void**)': moc_tum_ardrone_gui.cxx:(.text+0x6f0): multiple definition of `tum_ardrone_gui::qt_metacall(QMetaObject::Call, int, void**)' CMakeFiles/drone_gui2.dir/src/UINode/moc_tum_ardrone_gui.cxx.o:moc_tum_ardrone_gui.cxx:(.text+0x6f0): first defined here 

Code:

#include "tum_ardrone_gui.h" 
#include "RosThread.h" 
#include "PingThread.h" 

#include <QtGui> 
#include <QApplication> 
#include "ros/ros.h" 

// this global var is used in getMS(ros::Time t) to convert to a consistent integer timestamp used internally pretty much everywhere. 
// kind of an artifact from Windows-Version, where only that was available/used. 
unsigned int ros_header_timestamp_base = 0; 

int main(int argc, char *argv[]) 
{ 
    std::cout << "Starting drone_gui Node" << std::endl; 

    // ROS 
    ros::init(argc, argv, "drone_gui"); 

    RosThread t; 
    PingThread p; 

    // UI 
    QApplication a(argc, argv); 
    tum_ardrone_gui w; 

    // make them communicate with each other 
    t.gui = &w; 
    w.rosThread = &t; 
    p.gui = &w; 
    p.rosThread = &t; 
    w.pingThread = &p; 

    // start them. 
    t.startSystem(); 
    p.startSystem(); 
    w.show(); 

    // wait until windows closed.... 
    int ec = a.exec(); 

    // stop ROS again.... 
    t.stopSystem(); 
    p.stopSystem(); 

    std::cout << "Exiting drone_gui Node" << std::endl; 

    return ec; 
} 

Meine Frage ist: Stellen Sie sich vor ich meine UINode 10 Mal repliziert werden sollen. Muss ich meinen Code fest codieren und Änderungen an jedem Thread-Namen, jeder Klasse usw. vornehmen? Oder gibt es einen besseren Weg?

+1

machst du verschiedene Projekte oder möchtest du diese verschiedenen Knoten im selben Projekt erstellen? – coyotte508

+0

Sie müssen verschiedene Projekte sein (denke ich), weil ich den Pfad jedes Knotens ändern muss, den sie abonnieren und veröffentlichen (Robot1 und Robot2). Aber ich möchte sie kompilieren und gleichzeitig Robot1 mit UINode und Robot2 mit UINode2 steuern. –

+0

Was genau meinen Sie mit "Pfad von jedem Knoten"? Auf dem Dateisystem? Können Sie diese über Kommandozeilenparameter an Ihre Anwendung weitergeben? Dann müssten Sie diese nur noch auswerten, keine zusätzliche Anwendung erstellen müssen ... – Aconcagua

Antwort

2

Ich würde empfehlen, den gesamten Code, der in einem separaten Projekt üblich ist, zu sammeln und als eine Bibliothek (statisch oder gemeinsam genutzt) zu erstellen. Es kann sinnvoll sein, die Unterschiede als Polymorphie zu implementieren, sodass Sie Basisklassen in der Bibliothek haben und das Verhalten in Unterklassen der spezifischen Projekte implementieren oder überschreiben.

Auf diese Weise implementieren Sie nur die Unterschiede in jedem Projekt und verknüpfen sie alle mit der Bibliothek, die den gemeinsamen Code enthält.

Edit:

Vielleicht all dies nicht notwendig ist: Haben Sie daran gedacht, über Kommandozeilenparameter in jeder Instanz Ihrer Anwendung unterschiedliche Verhalten steuern?

Stellen Sie sich vor, Sie haben einen TCP-Client für welchen Zweck auch immer. Würden Sie es für die Verwendung mit jedem neuen Host neu kompilieren, mit dem Sie kommunizieren möchten? Sicherlich nicht. Stattdessen würden Sie die Hostadresse als Parameter übergeben, z. G. -h 127.0.0.1 -p 1977 oder -h 127.0.0.1:1977.

+0

Ich bin ein Anfänger: D Können Sie vereinfachen? –

+0

Bibliotheken sind so konzipiert, dass sie ein und denselben Code für verschiedene ausführbare Dateien freigeben. Ihr Vorteil ist, dass sie einmal kompiliert werden, und Sie können diesen bereits fertigen Code in eine beliebige Anzahl von Anwendungen einbinden (technisch korrekt: Sie verknüpfen sie). Haben Sie jemals die Option -l von gcc bemerkt (ich denke, es ist das gleiche für msvc). Mit dieser Option weisen Sie den Compiler an, dass er bereits kompilierten Code, der in einer Bibliothek bereitgestellt wird (zum Beispiel gegen Link), verwenden soll, wenn Sie eine QT-GUI-Anwendung erstellen. – Aconcagua

+0

Ich stimme zu. Dies wird als Refactoring bezeichnet. Polymorphismus ist jedoch nicht der einzige Weg, dies zu erreichen. – user2672165