QMainWindow centralWidget: Zugriff auf Klassen Member möglich?



  • Hallo,

    es wurde eine Klasse von QWidget mit Namen "Paint" abgeleitet und die Funktion paintEvent() hinzugefügt, um darin mit QPainter zu zeichnen. "Paint" wurde dann im Qt-Designer dem centralWidget von QMainWindow zugeordnet.

    Welche Möglichkeit gibt es nun von QMainWindow aus, auf die Membervariable "MyMember" und Funktion "MyFunc()" über einen Pointer zuzugreifen?

    // Paint.h
    
    class Paint : public QWidget
    {
    public:
        Paint(QWidget * parent = 0);
    
        double myMember;
        void   myFunc();
    
    protected:
        void paintEvent(QPaintEvent *);
    };
    
    Paint::Paint(QWidget * parent)
    {
    };
    
    void Paint::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
    
        painter.setPen(Qt::darkGreen);
        painter.drawRect(20, 20, 300, 200);
    };
    

    In der Qt Dokumentation ist der Zeiger "QWidget * centralWidget() const" aufgeführt. Über ihn ist es mir bislang nur gelungen auf die Qt Funktionen von centralWidget zuzugreifen, wie z.B. adjustSize() oder autoFillBackground() etc... Muss der QMainWindow Zeiger auf centralWidget() noch auf eine bestimmte Weise gekastet werden, damit der Zugriff auf die Member von "Paint" möglich wird?

    Oder gibt es einen ganz anderen Weg um den Zugriff auf die Member von "Paint" zu ermöglichen?



  • Der uic baut aus der ui Datei den Code, um die GUI zu erstellen. Das ist der Code, der hinter setupUi aufgerufen wird. Der automatisch generierte Code kann natürlich keine zusätzlichen Parameter übergeben. Den Parameter musst du also selber über einen Setter reingeben.



  • Hallo Mechanics,

    danke für Deine Antwort. An diesem Thema sitze ich nun schon pausenlos 3 Tage ohne weiter zu kommen. Könntest Du vielleicht anhand eines kurzen Code Schnipsel zeigen, wie und wo eine Parameterübergabe oder Zugriff auf "Paint" möglich ist? Das wäre wirklich eine große Hilfe!



  • Das ist jetzt ein völlig anderer Beitrag als der, auf den ich geantwortet habe. Beiträge so stark zu bearbeiten, macht überhaupt keinen Sinn.

    Um auf das zu antworten, was jetzt grad in deinem Post steht... 😉 Du könntest z.B. einfach static_cast<Paint*>(centralWidget()) benutzen.



  • Sorry, da hatten sich unsere Postings überschnitten. Ich hatte mein Eingangsposting neu geschrieben, weil mir mittlerweile klar worden war, dass das Hinzufügen eines zusätzliche Parameters im Konstruktor von "Paint" nicht funktionieren kann.

    Dein Code Schnipsel funktioniert einwandfrei!

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        // Liest myMember aus
        double Test1;
        Test1 = static_cast<Paint*>(centralWidget())->myMember;
    
        // Setzt myMember auf neuen Wert
        static_cast<Paint*>(centralWidget())->myMember = 99.9;
    }
    

    Was Du da so aus dem Handgelenk schüttelst ist wirklich erstaunlich. Allein hätte ich sicher noch lange sehr lange an diesem Problem gesessen. Vielen Dank dafür! 👍

    Beruhte Dein erster Vorschlag über die Setter Reingabe auch auf dem QMainWindow centralWidget() Pointer, verpackt in einem QMainWindow Setter? Oder war das ein ganz anderer Lösungsweg? Falls ja, würde mich der auch sehr interessieren. Ob Du mir den noch anhand eines kurzen Code Schnipsel zeigen könntest?



  • mireiner schrieb:

    Beruhte Dein erster Vorschlag über die Setter Reingabe auch auf dem QMainWindow centralWidget() Pointer, verpackt in einem QMainWindow Setter?

    Mir ist nicht ganz klar, wie der Satz gemeint ist. Ich meinte, du fügst deiner Paint Klasse einen Setter hinzu. So wie dieses myFunc, nur wäre es sowas wie setConfig(config). Im Konstruktor vom MainWindow würdest du eben die Config (du wolltest doch eine Config? Weiß ich nicht mehr genau) und übergibst sie deinem Widget.
    Wenn du öfter auf das Paint zugreifen willst, dann würde ich mir in deiner MainWindow Klasse auch eine entsprechende Membervariable vom Typ Paint* anlegen und den Wert nur ein mal mit static_cast holen. Zu viele Casts sind nicht gut.



  • Habe das jetzt mit Deinem Code so gelöst:

    //Paint.h
    #include <QWidget>
    #include <QPainter>
    #include <QPaintEvent>
    #include "Config.h"
    
    class Paint : public QWidget
    {
    public:
        Paint(QWidget * parent = 0);
    
    public:
        Config* Conf;
    
    protected:
        void paintEvent(QPaintEvent *);
    };
    
    //Paint.cpp
    #include "paint.h"
    
    Paint::Paint(QWidget * parent)
    {
        setStyleSheet("background-color: white;");
    };
    
    void Paint::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
    
        painter.setPen(Qt::darkGreen);
        painter.drawRect(Conf.X1, Conf.Y1, Conf.X2, Conf.Y2);
    };
    
    //MainWindow.h
    #include <QMainWindow>
    #include "Config.h";
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(Config* c, QWidget *parent=0);
        ~MainWindow();
    
    private:
        Ui::MainWindow *ui;
    };
    
    // MainWindow.cpp
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(Config* c, QWidget *parent)
        : QMainWindow(parent), ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        Paint *paint = dynamic_cast<Paint*>(centralWidget());
        paint->Conf = c;
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    //Main.cpp
    #include "mainwindow.h"
    #include <QApplication>
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        CConfig Conf;
        Conf.ReadConfigFile();
    
        MainWindow w(&C);
        w.show();
    
        return a.exec();
    }
    

    Gleich zu Anfang von Main() steht "Config", deren Pointer dann durch die Klassen weitergereicht wird. Im Konstruktor von MainWindow wird durch den dynamic_cast die Verbindung zu "Paint" hergestellt. Damit wird dynamic_cast nur einmal aufgerufen. Aus meiner Sicht funktioniert das gut. Oder gibt es noch ein besseren Design?



  • Das find ich schon soweit ok. Bessere oder andere Designs gibt immer. Das ist jetzt nicht so viel Code und da steckt auch nicht so viel dahinter, um großartig über bessere Alternativen zu diskutieren.



  • Nochmal vielen Dank an Dich! Dein Hinweis mit dem static_cast war meine Rettung.


Anmelden zum Antworten