Odwołanie do metod innej klasy



  • Witam.
    Chcę się odwołać do metod w klasie głównej z poziomu innej klasy.
    Potrzebuję użyć metody void MainWindow::Oblicz(), w klasie QWidget o nazwie SecondWindow.

    @// MainWindow.cpp

    void MainWindow::oblicz()
    {
    // kod
    };
    @

    @// SecondWindow.cpp
    void SecondWindow::Wynik()
    {
    oblicz();
    };@

    Jak to zrobić?



  • Przy tworzeniu instancji SecendWindow przekaż do niej parenta a następnie w metodzie Wynik wykonaj
    @MainWindow *existing;
    existing = qobject_cast<MainWindow *>(parrent);
    if (existing)
    {
    existing->oblicz();
    }@
    Drugim sposobem chyba łatwiejszym jest skorzystanie z sygnałów i slotów i w metodzie Wynik wykonać emit który połaczony jest connect'em z metodą oblicz.



  • Spróbowałem tym drugim sposobem.
    Nigdy wcześniej nie używałem connect'a, więc nie było potrzeby nic o nim wiedzieć, teraz poczytałem o nim w internecie, ale nie wiem dalej jak tego użyć.
    Zrobiłem coś takiego:

    @// MainWindow.cpp

    void MainWindow::oblicz()
    {
    // kod
    };
    @

    @// SecondWindow.cpp

    void SecondWindow::Wynik()
    {
    connect(Moj_Button,SIGNAL(clicked()),MainWindow,SLOT(oblicz()));
    emit oblicz();
    };@

    To pierwsze.
    Mam jeszcze drugi kłopot.

    Po utworzeniu okna QWidget, gdy zamykam okno główne, to to drugie okno (QWidget) pozostaje.
    Domyślam się, że jest to pewnie banalne pytanie (za co sorki), ale jak automatycznie zamykać resztę okien dziedziczących, po zamknięciu okna głównego?



  • oj całkiem nie tak.
    Connecta robisz w MainWindow
    a w SecondWindow tworzysz sygnał np:
    @signals:
    void oblicz();@
    w Wynik:
    void SecondWindow::Wynik()
    {
    emit oblicz();
    };
    następnie w MainWindow w momencie kiedy tworzysz instancje SecondWindow tworzysz connecta np:
    @secWindow = new SecondWindow(this);
    connect(secWindow,SIGNAL(oblicz()),this,SLOT(oblicz()));@



  • Dzięki. Działa, ale jednak nie do końca.
    Gdy np. zamiast oblicz() podstawiam metodę z głównej klasy tworzącej okno z dialogiem, to działa, ale gdy podstawię zamiast tego inną metodę, która tworzy plik .ini do konfiguracji, to już nie działa.
    Program się kompiluje, ale po kliknięciu buttona nic się nie dzieje.
    Dlaczego metoda tworząca okienko działa, a metoda tworząca .ini już nie?

    Dodam, że w:
    @secWindow = new SecondWindow(this);@
    wywaliłem "this", bo wtedy mi się nowe okienko "wtapiało" w to pierwsze, ale to chyba nie ma znaczenia.

    &edit.
    Kod tworzący .ini
    @void MainWindow::CreateIni()
    {
    QDir().mkdir("Settings");
    QFile file("Settings/Profile.ini");
    file.open(QIODevice::WriteOnly | QIODevice::Text);
    };@



  • Wklej tego connecta bo nie bardzo wiem o co chodzi. Poza tym wydaje mi się że kompletnie nie wiesz jak działają sygnały i sloty :D Może trzeba by zajrzeć do dokumentacji.

    Czy CreateIni() jest zadeklarowana jako slot ??



  • Mareczeq123 nie mógłbyś wrzucić większej ilości kodu źródłowego? Z pewnością łatwiejsze było by znalezienie błędu.
    Swoją drogą dlaczego nie używasz parenta dla SecondWindow? SecondWindod dlatego "wtapiał" Ci się w okno, z którego został zainicjowany, ponieważ dziedziczy po klasie QWidget. Jeżeli ma być on okienkiem to powinien dziedziczyć np. po QDialog. Jednocześnie użycie jako parenta MainWindow załatwi sprawę zamykania wszystkich okien, które są jego dziećmi. :)



  • bq. SecondWindod dlatego “wtapiał” Ci się w okno, z którego został zainicjowany, ponieważ dziedziczy po klasie QWidget. Jeżeli ma być on okienkiem to powinien dziedziczyć np. po QDialog. Jednocześnie użycie jako parenta MainWindow załatwi sprawę zamykania wszystkich okien, które są jego dziećmi. :)bq.

    Dlatego, że robię nowe formularze do nowych okienek w Designerze, żeby było szybciej, a tam jak próbowałem dać parenta to nie chciało się skompilować.

    Więcej kodu.

    @// MainWindow.cpp

    #include "MainWindow.h"
    #include "ui_MainWindow.h"

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    // (...) Konfiguracja itp.
    

    }

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

    void MainWindow::on_actionUstawienia_triggered()
    {
    settings = new Settings;

    connect(settings,SIGNAL(CreateIni()),this,SLOT(CreateIni()));
    
    settings->setMinimumSize( 422, 302 );
    settings->setMaximumSize( 422, 302 );
    settings->resize( 422, 302 );
    settings->setWindowTitle( "Ustawienia" );
    settings->show();
    

    }

    void MainWindow::CreateIni()
    {
    QDir().mkdir("Config");
    QFile file("Config/User.ini");
    file.open(QIODevice::WriteOnly | QIODevice::Text);
    }@

    @// MainWindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include "Settings.h"

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    private slots:
    void on_actionUstawienia_triggered();

    private:
    void CreateIni();

    private:
    Ui::MainWindow *ui;

    Settings *settings;
    

    }

    #endif // MAINWINDOW_H@

    @// Settings.cpp // (Zmienione z SecondWindow)

    #include "Settings.h"
    #include "ui_Settings.h"

    #include "MainWindow.h"

    Settings::Settings(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Settings), FileDir("/")
    {
    ui->setupUi(this);

    // (...) 
    

    }

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

    void Settings::on_ButtonIni_clicked()
    {
    emit CreateIni();
    }@

    @// Settings.h

    #ifndef SETTINGS_H
    #define SETTINGS_H

    namespace Ui {
    class Settings;
    }

    class Settings : public QWidget
    {
    Q_OBJECT

    public:
    explicit Settings(QWidget *parent = 0);
    ~Settings();

    private slots:
    void on_ButtonIni_clicked();

    private:
    Ui::Settings *ui;

    signals:
    void CreateIni();

    };

    #endif // SETTINGS_H@



  • Aby zadziałała Ci metoda CreateIni() musi być ona zdefiniowana jako slot. Czyli zamiast
    @private slots:
    void on_actionUstawienia_triggered();
    private:
    void CreateIni();@

    zmień na:
    @private slots:
    void on_actionUstawienia_triggered();
    void CreateIni();@



  • Działa znakomicie, dzięki.

    Kolejna sprawa. ;)

    Tworzę notatnik, by lepiej opanować QT.
    Mam textEdit, menuBar i w nim podmenu Edit z kilkoma opcjami.
    Teraz chcę, by w zależności czy textEdit jest pusty, opcja Znajdz w podmenu Edit była aktywna lub nie.

    Chciałem zrobić główną pętlę programu, w której co chwile by to sprawdzała, ale to nie chciało działać.
    Potem myślałem, by po kliknięciu podmenu Edit, sprawdzał się warunek if, ale nie wiem jak to zrobić.
    I chyba ostatnia możliwość....
    Czy opłaca się robić do tego QThread, by on sprawdzał czy textEdit jest pusty? i jak by go zrobić ew.?

    Jak wy byście to zrobili?



  • Podpinasz się slotem pod sygnał QTextEdit::textChanged(), sprawdzasz czy tekst jest pusty jeśli tak to ustawiasz w tym menu enable na false. Jak na przykład tutaj:
    @void MainWindow::on_textEdit_textChanged()
    {
    ui->textEdit->toPlainText().isEmpty() ? ui->menuEdit->setEnabled(false) : ui->menuEdit->setEnabled(true);
    }@
    Pewnie są może jakieś inne sposoby sprawdzenia długości tekstu w QTextEdit, natomiast piszę to z głowy więc z góry przepraszam jeśli nie jest to optymalny sposób.

    Używanie wątku w takiej sytuacji jest niepotrzebne. Używaj wątków w sytuacji, gdy masz jakieś czasochłonne zadanie/obliczenie, współpracujesz z bazą itp.

    Btw Nie uważasz, że temat tego 'wątku' na forum nie jest już zgodny z treścią w nim zawartą?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.