Klasy zagnieżdzone , problem z dostępem do obiektu.

0

Witam, od pewnego czasu męczę się z jedną rzeczą w QT, ale jest to problem bardziej dotyczący języka C++.Piszę aplikację do komunikacji z Arduino, poprzez port szeregowy , z wykorzystaniem biblioteki Qextserialport , mój problem wygląda następująco:

Klasa głowna "MainMenu.h"

class MainMenu : public Qdialog  
{
    Q_OBJECT 
public:
    explicit MainMenu(QWidget *parent = 0);
    ~MainMenu();
    Qextserialport * arduino
private slots:
    void on_testButton_clicked();
private:
    Ui::Pcr *ui; };

Definicja klasy "MainMenu.cpp"

MainMenu::MainMenu(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::MainMenu)
{
    ui->setupUi(this);
   arduino = new Qextserialport("/dev/ttyACM0");
   arduino.open(QIODevice::ReadWrite);
   if (arduino->isOpen)
    {
        //konfiguracja portu
    }
   else
    {
       //tu daje error jesli port jest nie otwarty
    }
}

MainMenu::~MainMenu()
{
    delete ui;
}

void MainMenu::on_testButton_clicked()
{
    // wysylam do arduino zmienna ktora informuje o przejscie do trybu testowego

    Test * testwindow = new Test(this);
    testwindow->show();
} 

Teraz po nacisnieciu przycisku Test, otwiera mi sie nowe okienko, ktore takze dziedziczy po Qdialog. Implementacja tej klasy wyglada nastepujaco:

class Test : public QDialog
{
    Q_OBJECT
public:
    explicit Test(QWidget *parent = 0);
    ~Test();
private slots:
    void on_MainMenuButton_clicked();
private:
    Ui::Test *ui;

}; 
Test::Test(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Test)
{
    ui->setupUi(this);
}

Test::~Test()
{
    delete ui;
}

void Test::on_MainMenuButton_clicked()
{
    Test::close();
    //delete ui;
} 

i w klasie test chce tez wysylac i odbierac informacje do arduino poprzez ten sam obiekt utworzony w klasie main menu. Problem ten probowalem rozwiazac na nastepujace sposoby :

w konstruktorze klasy test pisałem po prostu MainMenu::arduino->write("BLABLABLA"), niestety kompilator protestuje,

bawilem sie klasami zaprzyjaznionymi i probowalem dostac sie do obiektu w ten sam sposob co powyzej,

rozwiazaniem na sile bylo dodanie do klasy qdialog.h obiektu arduino w ten sam sposob, w jaki tworze obiekt w klasie MainMenu, jednak wydaje mi sie ze jest to rozwiazanie nie poprawne i jesli np, skompiluje swoja aplikacje na uC z rdzeniem ARM , na ktorym mam linuxa i biblioteki Qt to mimo iz aplikacja skompiluje sie poprawnie to na Armie nie bedzie dzialac tak jak tego potrzebuje.

probowalem dodac klase "Api" ktora dziedziczy po Qdialog, tam dodawalem obiekt arduino, i zmienilem klasy MainMenu i klase Test aby dziedziczyly one po klasie api, jednak robilem to nieprawidlowo bo kompilator protestowal :)

Nie mam juz wiecej pomyslow jak sie dostac do tego obiektu niestety, szukalem rozwiazania w google, nie wiem czy ustawienie arduino jako singletonu jest poprawnym rozwiazaniem, jesli tak to jak to zrobic ? Czy problem polega na tym, że kompilator tak naprawne nie wie że obiekt klasy MainMenu a tym samym instancja arduino jest juz stworzona, dlatego nie moge sie do niej dostac ? jesli tak to jak oszukac kompilator, bo klasa MainMenu jest tworzona wraz z uruchomieniem okna a pozostale klasy dopiero po niej.

Moglbym prosic o jakies zrodla gdzie moglbym poczytac o rozwiazaniach takich problemow ?

Z gory dziekuje za odpowiedzi i poswiecony czas , pozdrawiam!

1

Zagnieżdżenie klasy nie zmienia normalnych relacji apropos dostępu,powoduje tylko,że obiekty klasy zagnieżdżonej można tworzyć wyłącznie w klasie zagnieżdżającej.
Co do przekazania,to do konstruktora klasy Test dodaj wskaźnik na Qextserialport:

explicit Test(Qextserialport *port,QWidget *parent = 0);

i tworząc obiekt w jakiejś funkcji mainmenu:

Test *t=new Test(arduino,this);

nie ma kija,żeby nie poszło

0

Dzieki serdeczne poszlo!

Teraz, w ten sposob mam dostep do arduino w konstruktorze klasy test, moge zmieniac opcje czytac etc, a co jesli bym chcial miec dostep do obiektu arduino, aby moc odczytywac/pisac dane np z funkcji w klasie Test?

Musze takze do ich wywolania dopisac wskaznik na port?

1

Nie.Zmodyfikuj definicję klasy Test po prostu:

class Test : public QDialog
{
    Q_OBJECT
public:
    explicit Test(QWidget *parent = 0);
    ~Test();
private slots:
    void on_MainMenuButton_clicked();
private:
    Ui::Test *ui;
    Qextserialport *arduino; 
};

Definicja konstruktora zaś będzie wyglądała tak:

explicit Test(Qextserialport *port,QWidget *parent = 0):arduino(port)
{}
0

niestety w ten sposob nie dziala, mam pytanie dlaczego w klasie test mowisz ze mam zadeklarowac obiekt arduino ? Ten obiekt musi byc wczesniej w klasie main menu, w klasie test mam z niego korzystac.

w klasie test tak jak mowiles zmienilem definicje konstruktora na

explicit Test(QextSerialPort *port, QWidget *parent = 0); 

nastepnie jego implementacja:

 Test::Test(QextSerialPort *port, QWidget *parent) :
    QDialog(parent), 
{

 }

w klasie main menu po wcisnieciu buttona tworzy sie obiekt klasy test,wywolalniem

 Test * testwindow = new Test(arduino,this); 
1
 Test::Test(QextSerialPort *port, QWidget *parent) :
    QDialog(parent), arduino(port)
{
 
 }

Tak to ujmując dokładnie ma wyglądać.Od teraz w całej klasie Test będziesz miał dostęp do obiektu Qextserialport wskazywanego przez wskaźnik andruino.A że w konstruktorze zapodajesz wskaźnik na obiekt utworzony w klasie MainMenu,to tego właśnie obiektu będziesz używać-czyli masz to,co chciałeś uzyskać

0

Ok, juz czaję! Dzieki jeszcze raz, pozdrawiam!

1 użytkowników online, w tym zalogowanych: 0, gości: 1