Wie kann ich auf Variablen einer anderen Header-Datei zugreifen



  • Hallo,
    ich arbeite an einem Programm zum Lernen von Vokabeln.
    Die Vokabeln werden in einem Array gespeichert. Will ich eines der Vokabeln ändern, kann man dafür den Eintrag des QLineWidgets doppelklicken. Es öffnet sich ein zweites Fenster mit den nötigen Möglichkeiten den Eintrag zu ändern.
    Nur leider bekomme ich die Fehlermeldung, dass die Terme nicht deklariert sind.
    Habe gegooglet und den einzigen Hinweis, den ich finden konnte ist das Stichwort extern zu verwenden. Aber das klappt auch nicht.

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QString>
    #include <QFile>
    #include "edit.h"
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
        QString voc_list[100];
        QString current_file_path = "";
        QFile current_file;
        QString default_path = "";
        QString temp_array[100];
        QString native[100];
        QString foreign[100];
        QString comment[100];
        QString leanred[100];
        unsigned __int8 current_item = 0;
    
    private slots:
        void on_actionOpen_Vocabulary_File_triggered();
    
        void on_listWidget_doubleClicked(const QModelIndex &index);
    
    private:
        edit *dialog;
        Ui::MainWindow *ui;
    
    };
    
    #endif // MAINWINDOW_H
    

    edit.h

    #ifndef EDIT_H
    #define EDIT_H
    
    #include <QDialog>
    
    namespace Ui {
    class edit;
    }
    
    class edit : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit edit(QWidget *parent = 0);
        ~edit();
    
    private slots:
        void on_pushButton_edit_confirm_clicked();
    
    private:
        Ui::edit *ui;
    };
    
    #endif // EDIT_H
    

    Ausschnitt aus mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QFile>
    #include <QFileDialog>
    #include <QMessageBox>
    #include <QTextStream>
    #include <QSize>
    #include <QList>
    #include "edit.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    //...
    
    void MainWindow::on_listWidget_doubleClicked(const QModelIndex &index)
    {
        current_item = ui->listWidget->currentIndex().row();
        dialog = new edit(this);
        dialog->show();
    }
    

    edit.cpp

    #include "edit.h"
    #include "ui_edit.h"
    #include "mainwindow.h"
    
    edit::edit(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::edit)
    {
        ui->setupUi(this);
    }
    
    edit::~edit()
    {
        delete ui;
    }
    
    void edit::on_pushButton_edit_confirm_clicked()
    {
        native[current_item] = ui->lineEdit_native_edit->text();
        foreign[current_item] = ui->lineEdit_foreign_edit->text();
        comment[current_item] = ui->lineEdit_comment_edit->text();
    
        ui->plainTextEdit->setText(native[current_item] + "\n" + foreign[current_item] + "\n" + comment[current_item]);
    }
    

    Eine de Fehlermeldungen

    Fehler: 'native' was not declared in this scope



  • Dein Problem ist hier vermutlich die Eltern-Kind-Beziehung.

    "edit" ist ein Kind von "MainWindow".
    D.h. MainWindow kennt "dialog" ( vom Type "edit" ), aber "dialog/edit" kennt "MainWindow" nicht.

    es gibt mehrere Möglichkeiten wie du zum Ziel kommst.

    1. Du erzeugst zusätzlich eine Art Datenklasse, die ebenfalls in MainWindow als Kind-Objekt ( genau wie "dialog" ) enthalten ist, die aber nur deine gewünschten Daten enthält. Und wenn du "dialog" erzeugst ( mit new ) übergibst du eine Referenz auf das Objekt der Datenklasse an "dialog" im Konstruktor.

    2. Prinzpiell kennt aber "edit" "MainWindow" schon, aber nur als "parent" vom Typ "Object*" und nicht vom Typ "MainWindow*".

    D.h. wenn du auf das Object als Mainwindow zugreifen willst castest du "parent" einfach auf den Typ "MainWindow" und kannst dann zugreifen.

    void edit::on_pushButton_edit_confirm_clicked()
    {
        MainWindow *meinbesitzer = dynamic_cast<MainWindow*> ( parent() );
        if ( !meinbesitzer  )
        {
            // irgendeine Art von Fehlerhandling, da der Besitzer von "edit" kein "MainWindow" ist
            return;
        }
        meinbesitzer->native[ 
        ....
    }
    

    Ist jetzt nur bei mir im Hinterkopf gewachsen ,sollte aber passen.
    Wobei mir die Variante mit der Datenklasse irgendwie besser gefällt.

    PS: gibt natürlich noch deutlich mehr Varianten. Mit Signals und Slots könnte man da sicher auch einiges machen.



  • Danke 🙂
    habs lösen können, indem ich die Arrays in der mainwindow.cpp deklariert habe und in einer neuen Header-Datei diese mit dem Stichwort extern aufgerufen habe



  • Hatte soeben ein ähnliches Problem und mir hat zusätzlich zu deinem Beitrag (Stichwort extern) dieser Artikel geholfen :

    https://stackoverflow.com/questions/10422034/when-to-use-extern-in-c

    Hier noch der relevante Code (Auszug) vom user "dreamlax". Dort wird eine externe Variable in einem Header deklariert, welcher von mehreren anderen "Programmen" gleichzeitig genutzt wird.

    Die HEADER_Guards nicht vergessen!

    header.h:

    #ifndef HEADER_H
    #define HEADER_H
    
    // any source file that includes this will be able to use "global_x"
    extern int global_x;
    
    void print_global_x();
    
    #endif
    

    source1.cpp:

    #include "header.h"
    
    // it needs to be defined somewhere
    int global_x;
    
    int main()
    {
        //set global_x here:
        global_x = 5;
    
        print_global_x();
    }
    

    source2.cpp:

    #include <iostream>
    #include "header.h"
    
    void print_global_x()
    {
        //print global_x here:
        std::cout << global_x << std::endl;
    }
    

    Ich habe das Gefühl, dass dies kein Minimalbeispiel ist (braucht es die Deklaration der print_global_x() wirklich im header?), aber ich konnte darauf aufbauend mein Problem lösen



  • 👎 Mit globalen Variablen löst man keine Probleme, sondern schafft sie erst!

    Such mal nach "C++ why global variables are bad", dann landest du u.a. bei Are global variables really all that bad?


Anmelden zum Antworten