QT5 - kilka pytań początkującego

0

Witam

Postanowiłem nauczy się biblioteki/frameworka QT w wersji 5.
Czytałem już kilka kursów/lekcji itp ale nie znalazłem odpowiedzi na swoje pytania.

namespace Ui {
class MainWindow;
} 
class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private slots:

private:
    Ui::MainWindow *ui;
};
  1. Czym jest Q_OBJECT - czy jest konieczne w każdej klasie oraz dlaczego nie ma błedu z powdu braku średnika na końcu?

  2. Czy stosowanie Qt Designer jest konieczne żeby używać QT - np. z powodu qmake zamist make ....

  3. Nie rozumiem tych fragmentów kodu:

namespace Ui {
class MainWindow;
}
private:
    Ui::MainWindow *ui;

Czy Ui::MainWindow to to samo co MainWindow? Jak w takim razie jest możliwe zadekalrować okno potem je defniować a w defnicji zawrzeć wskaźnik do okna?

 
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MainWindow window;
    window.show();

    return app.exec();
}

4.1) Co to jest QApplication?
4.2)Czemu stworzono specjalną klasę QApplication? Za co ona odpowiada?
4.3)Gdzie jest jej definicja - przynajmniej *.hpp
4.4)Czy to ona obsługuje zdarzenia w sposób domyślny a kiedy ja chce zmienić zachowanie aplikacji to musze utworzyć klase dziedzicząca z QAppliaction i przesłonić odpowiednie metody?

  1. Wprowadziłem małą modyfikację.
 int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    MainWindow wi;
    wi.show();

    return a.exec();
}

Jak stworzyć drugie okno które było by inne od pierwszego i dlaczego one są takie same?

  1. Jak budować aplikacje opartą na kontrolkach za pomocą QT - czy użycie Designera jest obowiązkowe?
    Powiedzmy że wy-klikałem sobie program w Qt Designer czy potem mogę dodawać klasy, funkcję oraz pliki*. hpp i *.cpp jak w normalnym projekcie - boję się żeby nie naruszyć jakiegoś porządku czy czegoś nie zepsuć.
    Generuje on pliki - czy ja mam/mogę je modyfikować?
3

Słabiutko u Ciebie z obsługą google'a. Niektórzy by już polecili zmianę zawodu.

  1. Q_OBJECThttp://doc.qt.io/qt-5.7/qobject.html#Q_OBJECT
  2. nie
  3. forward-deklaracja klasy wygenerowanej przez designera. To nie jest to samo co MainWindow w innym namespace.
    4.1) http://doc.qt.io/qt-5/qapplication.html
    4.2) głównie eventloop, inicjalizacja różnych elementów biblioteki Qt.
    4.3) F2 w Qt Creatorze polecam. Albo google. http://code.qt.io/cgit/qt/qtbase.git/tree/src/widgets/kernel/qapplication.cpp
    4.4) Dziedziczenie po QApplication raczej nie jest wskazane. Ani konieczne.
  4. Polecam użycie innej klasy jeśli chcesz mieć inne okno.
  5. Nie jest obowiązkowe, ale jest ułatwieniem. Popatrz na przykłady w Qt (examples).
1

czy użycie Designera jest obowiązkowe?

Nie, ale do Qt polecam raczej Creatora a nie Designera.
Qt Creator ma Designera wbudowanego, ale jest pełnym IDE.

2
  1. makro które moc (narzędzie Qt) używa do wykrycia, czy należy wygenerować meta dane. Bez tego sygnały i sloty ci nie zadziałają.
  2. nie, ale jest wygodne
  3. kq wyjaśnił - generalnie chodzi o to by oddzielić kod generowany przez Qt Designer od twojego kodu - nie dotykaj jak go używasz.
  4. To jest obiekt reprezentujący za ogólne funkcje aplikacji. Obiekt ten odpowiada, za inicjalizację, zrządzanie: zdarzeniami, stylami, lokalizacją aplikacji. Ogólnie to jest obiket interesujący dopiero przy wysokim poziomie zaawansowania, nie dotykaj (nie będziesz miał takiej potrzeby) przez najbliższe parę lat.
  5. Jak chcesz drugie, okno to musisz je najpierw napisać, możesz mieć kilka "głównych" okien, ale zwykle to nie ma sensu. Inne okna powinny być tworzone przez główne okno, by trzymać się pewnych wytycznych jak tworzyć dobre UI. Inaczej mówiąc, nie ma potrzeby być dotykał teraz funkcji main (może jak będziesz robił splash window).
  6. Nie ma obowiązku używania Qt designer, jest tot po prostu wygodne. Jednak dobrze będziesz jak na początku nie będziesz go używał, by zrozumieć, co tak naprawdę Designer robi za ciebie. Możesz dodawać dowolną ilość klas, ile jest ci potrzebne. I więcej tym zwykle lepiej. Im szybciej nauczysz się dzielić na logiczne kawałki tym lepiej i to niezależnie czy używasz Qt czy czegokolwiek innego.
0

makro które moc (narzędzie Qt) używa do wykrycia, czy należy wygenerować meta dane. Bez tego sygnały i sloty ci nie zadziałają.

Czym jest MOC , czy to jakby dodaktowy program wchodzący w skład kompilatora używanego przez Qt Creator czy tez Qt zastępuje preprocesor np. ten z GCC?

MOC odczytuje plik nagłówkowy *.hpp . Jeśli stwierdzi jedną lub więcej deklaracji klasy, które zawierają makra Q_OBJECT plik źródłowy zawierający kod meta- obiektu dla tych klas. Kod meta- obiektu jest wymagany do poprawnego działania mechanizmu sygnałów i slotów, rtti oraz dynamicznego systemu własności.

Czy to właśnie z tego powodu kompilacja aplikacji trwa (dość) długo?

Nie ma obowiązku używania Qt designer, jest tot po prostu wygodne. Jednak dobrze będziesz jak na początku nie będziesz go używał, by zrozumieć, co tak naprawdę Designer robi za ciebie. Możesz dodawać dowolną ilość klas, ile jest ci potrzebne. I więcej tym zwykle lepiej. Im szybciej nauczysz się dzielić na logiczne kawałki tym lepiej i to niezależnie czy używasz Qt czy czegokolwiek innego.

Ja już w innych projektach dodawałem sobie pliki *.cpp i *.hpp tylko bałem się tego Qt Desginera ;) Boję się żeby czegoś nie zepsuć

  • w sieci widziałem przykłady jak ktoś definiował wygląd kontrolki za pomocą CSS, u mnie w projekcie testowej aplikacji jest jakiś plik *.ui a konfiguracja projektu odbywa się chyba poprzez ręczną zmianę w pliku *.pro

7)**Nie wiem czy dobrze rozumiem funkcjie main() **

   QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();

Nikt nie tłumaczy dlaczego " Ogólnie to jest obiekt interesujący dopiero przy wysokim poziomie zaawansowania, nie dotykaj (nie będziesz miał takiej potrzeby) przez najbliższe parę lat."
Gdzie są obsługiwane zdarzenia ani czy ja w ogóle mogę do funkcji main() coś wsadzić - nie wiem też co robi a.exec() ani kiedy zakończy się program.

//Jeżeli dobrze rozumiem to
Najważniejszą rzeczą jaką trzeba wiedzieć o QApplication jest to że metoda exec() uruchamia pętlę zdarzeń dzięki czemu mechanizm sygnałów i slotów może działać.
Mówiąc prościej , jeśli nie ma pętli zdarzeń , zdarzenia nie mogą być obsłużone więc UI będzie po prostu nic nie robić.//

8)Czy Qt obsługuje Windows XP - nie ma go na liście wspieranych platform ale czy jest możliwość przebudować bibliotekę?

0

8)Czy Qt obsługuje Windows XP - nie ma go na liście wspieranych platform ale czy jest możliwość przebudować bibliotekę?

na pewno 5.5.1 obsługuje. 5.7 jeszcze nie testowałem.
Co do kompilatora: nie używam Qt w wersji GCC, więc nie wiem, ale powinna pod XP działać.

Używam Visual C++. Ostatni Visual który działa pod XP to 2010, i jeszcze do niedawna oficjalne paczki Qt pod ten kompilator były.
Najnowszą wersję musiałbym przekompilować - nie próbowałem jeszcze.

EDIT: VS2010 to jeżeli chcę kompilować na XP - nie ma problemu by używać np. VS2015 pod Win7+ i uruchamiać skompilowany program pod XP.

0

Witajcie

9)Nie rozumiem jak pętla główna w Qt.

 int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MainWindow window;
    window.show();
    return app.exec();
}

9.1) Skąd funkcja QApplication::exec() "wie" że musi obsłużyć zdarzenia okna?
Nie widzę żeby gdzieś tam występowała funkcja typu

 registerWindow();

9.2) Powiedzmy że posiadam funkcje

void callMe();

Czy mogę skłonić QApplication do tego by co obieg pętli głównej wywoływała ją?

Przykład
Mam klasę która sprawdza bieżący czas systemowy i chce by metoda doIt() była wywoływana co obieg programu.

Potrzebuję jakoś "przejąć kontrolę nad moją aplikacją" - wiem jak to zabrzmi ale w SFML było to prostsze (ma w końcu prostotę w nazwie) tworzyłem własną pętle główną w oparciu o ustalony schemat i wszystko wiedziałem a teraz jedyne co mi przychodzi do głowy to stworzyć nowy wątek ale nie wiem czy jak ta funkcja QApplication::exec() się skończy bo np okno zostanie zamknięte to co się stanie z moim wątkiem.

1

Pętla główna (ani inne eventloopy Qt) nie używa busy waitów. Pod *nixami używa select albo czegoś podobnego, pod Windowsem WaitForMultipleObjects. Okienka same się rejestrują u rodzica, a jeśli rodzica nie mają to w QApplication::instance().

Jeśli chcesz coś cyklicznie wykonywać to użyj QTimer

0

A co jeśli ja chce panować nad aplikacją? W sensie mam klasę, która jest główna i to ona zarządza programem.
Nie chce cyklicznie jej wywoływać bo ona jest tą główną. Fajnie by było gdyby można było dodać własne funkcje do głównej pętli QAplication;

Na razie mam pomysł by dodać warunek w pętli mojej klasy, tylko żeby się komunikować z oknem (odebrać odpowiedni sygnał od usera np: "pokaz okno ponownie za 5 minut") musiałbym bym zrobić jakąś zmienną globalną.

if(showWindow == true)
{
    QApplication a(argc, argv);

    MainWindow w;
    w.show();

    return a.exec();
}
2

Przecież to wszystko możesz już zrobić, m.in. za pomocą QTimera.

0

A czy ten Qtimer ustawić w oknie czy w głównej pletli czy w main?

Nie mogę załapać schematu budowy aplikacji w QT.
Jak je łączyć z moim kodem, może to jakieś chwilowe zaćmienie ale nie wiem nawet jakie pytanie zadać.

Kiedy moja aplikacja kończy działanie? - obiło mi się o uszy/oczy że gdy ostanie okno czy ?widget? zostanie wyrejestrowany czy tam zamknięty - co gdy ja chce aby aplikacja działała w tle ?** Jaki powinien być schemat czy też jak powinna wyglądać funkcja main() w takim programie?**

0

Witam

Mam problem z QtCreatorem - otóż gdy stworzyłem projekt to bawiąc się Designerem "wygenerowałem kod" - funkcję która była wołana po kliknięciu przycisku.
Problem polega na tym że zmieniłem nazwę na bardziej sensowną i teraz podczas kompilacji dostaję błędy.
Zmieniłem nazwę funkcji( a raczej przycisku po czym wybrałem z menu kontekstowego "przejdź do slotu" ) z

pushButton_2_clicked()

na

on_closeApp_clicked()

problematyczna metoda jest generowana przez MOC - błąd jest w pliku moc_mainwindow.cpp

void MainWindow::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
    if (_c == QMetaObject::InvokeMetaMethod) {
        MainWindow *_t = static_cast<MainWindow *>(_o);
        Q_UNUSED(_t)
        switch (_id) {
        case 0: _t->refreshProgressBar(); break;
        case 1: _t->on_pushButton_2_clicked(); break;
        case 2: _t->on_pushButton_clicked(); break;
        case 3: _t->on_shutdownSystemNow_clicked(); break;
        case 4: _t->on_remindLater_clicked(); break;
        case 5: _t->on_closeApp_clicked(); break;
        default: ;
        }
    }
    Q_UNUSED(_a);
}
0

Wywołaj qmake jeszcze raz. (prawy klawisz na projekcie)

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