Atom

2009
03
cze

Kurs Qt – część 1 – sygnały, sloty i własne widgety

Kategoria: Kurs Qt, Programowanie, Qt, TechblogMatthew @ 20:27

Miał być w piątek, więc wrzucam dzisiaj. ;) Z tej części kursu poznamy klasę głównego okna w Qt, jak tworzyć własne widgety oraz na czym polega mechanizm sygnałów i slotów. Miłej lektury.

Główne okno w Qt reprezentuje klasa QMainWindow. Jest to chyba najczęściej dziedziczona klasa. Pozwala nam na umieszczanie menu oraz statusu. Najprostszy program z QMainWindow wygląda tak:

mainwindow.hpp:

1
2
3
4
5
6
7
8
9
10
11
12
#ifndef MAINWINDOW_HPP
#define MAINWINDOW_HPP

#include <QMainWindow>

class MainWindow : public QMainWindow
{
public:
   MainWindow();
};

#endif // MAINWINDOW_HPP

W 4. linijce załączamy nagłówek klasy QMainWindow. W 6. definiujemy własną klasę MainWindow, która dziedziczy po QMainWindow. Natomiast w 9. definiujemy konstruktor naszej klasy, którzy przyda nam się później do tworzenia własnych menu i paska statusu. W ten oto sposób zrobiliśmy nasz pierwszy widget w Qt. :]

mainwindow.cpp:

1
2
3
4
5
#include "mainwindow.hpp"

MainWindow::MainWindow()
{
}

main.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <QApplication>
#include <QMainWindow>

#include "mainwindow.hpp"

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

   window.show();

   return app.exec();
}

W 9. linijce tworzymy obiekt klasy naszego okna, a w 11. wyświetlamy to okno. Po kompilacji i uruchomieniu pokazuje się nam okno. Gdy już się pozachwycamy jacy jesteśmy piękni, mądrzy i wspaniali możemy przejść do dalszej zabawy z naszym okienkiem.

Dołożymy przycisk, dzięki któremu (za pomocą sygnałów i slotów) będziemy mogli zamknąć okno (to dla tych, którzy mają problem w trafienie w ‘x’ na belce okna ;)). A wygląda to tak:

mainwindow.hpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef MAINWINDOW_HPP
#define MAINWINDOW_HPP

#include <QAainwindow>
#include <QTextCodec>
#include <QPushButton>

class MainWindow : public QMainWindow
{
private:
   QPushButton *button;

public:
   MainWindow();
};

#endif // MAINWINDOW_HPP

W linii 5. i 6. dołączamy nagłówki, pierwszy odpowiada za kodowanie, drugi zawiera klasę przycisku. Natomiast w 11. tworzymy wskaźnik na obiekt klasy przycisku.

mainwindow.cpp:

1
2
3
4
5
6
7
8
9
#include "mainwindow.hpp"

MainWindow::MainWindow()
{
   QTextCodec::setCodecForTr (QTextCodec::codecForName ("UTF-8"));

   button = new QPushButton (tr("&Wciśnij mnie ;)"), this);
   button->setGeometry(25, 15, 150, 75);
}

W konstruktorze (linia 5.) ustawiamy kodowania, dla tłumaczeń, na UTF-8, dzięki czemu będziemy widzieć polskie (i nie tylko) krzaczki. Jeżeli mimo ustawienia UTF-8 nadal masz dziwne znaki, to najwyższy czas, żebyś zaczął kodować swoje źródła w UTF-8. :P Oprócz kodowania dla tłumaczeń (o których będzie innym razem), może również ustawić kodowania dla lokali (setCodecForLocale) oraz standardowych stringów (setCodecForCStrings). W linii 7. przypisujemy do naszego wskaźnika przycisku obiekt dynamiczny klasy QPushButton. Pierwszy argument jaki podajemy jest tekst który znajduje się na przycisku. & postawiony przed ‘W’ pozwala nam na wciskanie tego przycisku poprzez skrót Alt-w. Nasz napis przechodzi przez funkcję tr(). Służy ona do tłumaczenia interfejsu aplikacji na inne języki (jak tłumaczyć i wykorzystać do tego Qt Linguist napiszę kiedy indziej). Drugi argument, to wskaźnik na rodzica, na którym ma być wyświetlany nasz widget. Oprócz tego pozwala to, na pomijanie operatora delete, gdyż Qt sam usuwa z pamięci obiekty widgetów, które są „potomkami” (w sensie bycia umieszczonym na formatce rodzica, nie w sensie dziedziczenia) innych widgetów. W następnej linii ustawiamy wymiary i położenie naszego przycisku (kolejno: x, y, szerowość oraz wysokość). Po kompilacji i uruchomieniu pokazuje nam się okno z przyciskiem który możemy sobie poklikać. ;)

Żeby dodać trochę więcej interakcji z programem, podepniemy sygnał kliknięcia przycisku do slotu zamknięcia aplikacji:

mainwindow.hpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef MAINWINDOW_HPP
#define MAINWINDOW_HPP

#include <QApplication>
#include <QMainWindow>
#include <QTextCodec>
#include <QPushButton>

class MainWindow : public QMainWindow
{
private:
   QPushButton *button;

public:
   MainWindow();
};

#endif // MAINWINDOW_HPP

W mainwindow.hpp dodajemy tylko nagłówek klasy QApplication.

mainwindow.cpp:

1
2
3
4
5
6
7
8
9
10
11
#include "mainwindow.hpp"

MainWindow::MainWindow()
{
   QTextCodec::setCodecForTr (QTextCodec::codecForName ("UTF-8"));

   button = new QPushButton (tr("&Wciśnij mnie ;)"), this);
   button->setGeometry(25, 15, 150, 75);

   connect(button, SIGNAL(clicked()), qApp, SLOT(quit()));
}

W konstruktorze klasy MainWindow dodajemy połączenie między przyciskiem a naszą aplikacją. Przycisk wysyła sygnał kliknięcia do qApp (jest to makro, które reprezentuje obiekt naszej aplikacji), który to wywołuje metodę wyjścia z programu. Taką aplikację możemy już zamknąć przy pomocy naszego przycisku.

Teraz pokażę jak tworzyć własne sloty. Stworzymy dodatkowy przycisk i etykietę, którą będziemy zmieniali tym przyciskiem:

mainwindow.hpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#ifndef MAINWINDOW_HPP
#define MAINWINDOW_HPP

#include <QApplication>
#include <QMainWindow>
#include <QTextCodec>
#include <QPushButton>
#include <QLabel>

class MainWindow : public QMainWindow
{
   Q_OBJECT

private:
   QPushButton *button;
   QPushButton *butlab;
   QLabel *label;

public:
   MainWindow();

private slots:
   void foo();
};

#endif // MAINWINDOW_HPP

Nową rzeczą jest marko Q_OBJECT, które musi być załączone, w prywatnej sekcji, każdej klasy, która ma własne sygnały lub sloty (lub inne możliwości dostarczane przez meta-object system Qt). Taka klasa musi również dziedziczyć (bezpośrednio lub pośrednio) po klasie QObject. Deklarujemy również prywatny slot. W rzeczywistości jest to metoda, którą możemy normalnie wywoływać, bez łączenia z sygnałami. Jeden sygnał może być podpięty do wielu slotów, tak samo jak jeden slot może przyjmować wiele różnych sygnałów. Jedyne ograniczenie jest takie, że slot nie może przyjmować więcej argumentów niż ma ich sygnał (tworzeniem sygnałów zajmiemy się innym razem).

mainwindow.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "mainwindow.hpp"

MainWindow::MainWindow()
{
   QTextCodec::setCodecForTr(QTextCodec::codecForName ("UTF-8"));

   label = new QLabel(tr("Smutna etykieta :(", this);
   label->setGeometry(5, 5, 150, 30);

   button = new QPushButton(tr("&Wciśnij mnie ;)"), this);
   button->setGeometry(5, 35, 100, 30);

   butlab = new QPushButton(tr("&Zmień napis"), this);
   butlab->setGeometry(5, 65, 100, 30);

   connect(button, SIGNAL(clicked()), qApp, SLOT(quit()));
   connect(butlab, SIGNAL(clicked()), this, SLOT(foo()));
}

void MainWindow::foo()
{
   label->setText(tr("Wesoła etykieta :)"));
}

Mam nadzieję że kod konstruktora jest w miarę jasny. Na końcu łączymy sygnał przycisku butlab ze slotem foo() obiektu klasy MainWindow. Metoda foo() zmienia tekst naszej etykiety. Jak widać, żadna magia. :)

A na sam koniec nasza aplikacja z prostym menu i paskiem statusu:

mainwindow.hpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#ifndef MAINWINDOW_HPP
#define MAINWINDOW_HPP

#include <QApplication>
#include <QMainwindow>
#include <QTextCodec>
#include <QPushButton>
#include <QLabel>
#include <QMenuBar>
#include <QStatusBar>

class MainWindow : public QMainWindow
{
   Q_OBJECT

private:
   QPushButton *button;
   QPushButton *butlab;
   QLabel *label;

   QMenu *menu;
   QAction *quitAction;

   void createMenus();
   void createStatusBar();

public:
   MainWindow();

private slots:
   void foo();
};

#endif // MAINWINDOW_HPP

W nagłówku klasy naszego okna dodajemy wskaźniki na obiekty menu oraz akcji.

mainwindow.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include "mainwindow.hpp"

MainWindow::MainWindow()
{
   QTextCodec::setCodecForTr (QTextCodec::codecForName ("UTF-8"));

   createMenus();
   createStatusBar();

   label = new QLabel(tr("Smutna etykieta :("), this);
   label->setGeometry(5, 15, 150, 30);

   button = new QPushButton(tr("&Wciśnij mnie ;)"), this);
   button->setGeometry(5, 45, 100, 30);

   butlab = new QPushButton(tr("&Zmień napis"), this);
   butlab->setGeometry(5, 75, 100, 30);

   connect(button, SIGNAL(clicked()), qApp, SLOT(quit()));
   connect(butlab, SIGNAL(clicked()), this, SLOT(foo()));

   setMinimumSize(200, 200);
   resize(480, 320);
}

void MainWindow::foo()
{
   label->setText(tr("Wesoła etykieta :)"));
}

void MainWindow::createMenus()
{
   menu = menuBar()->addMenu(tr("&Plik"));

   quitAction = new QAction(tr("&Wyjście"), this);
   quitAction->setStatusTip(tr("Wyjdź z programu."));
   connect (quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
   menu->addAction(quitAction);
}

void MainWindow::createStatusBar()
{
   statusBar()->showMessage(tr("Gotowy"));
}

Konstruktor klasy naszego okna głównego doczekał się ustawień minimalnego rozmiaru okna (linia 22.) oraz zmiany wielkości okna (linia 23.). Znacznie ciekawsze jest to co się dzieje w metodach createMenus() oraz createStatusBar(). Pierwsza metoda tworzy poszczególne menu. Dodajemy menu „Plik” (linia 33.), tworzymy akcję „Wyjście” (linia 35.), której podpowiedź będzie wyświetlana w belce statusu (linia 36.), podłączamy tą akcję do slotu wyjścia z aplikacji oraz dodajemy ją do menu (linie 37. i 38). W metodzie createStatusBar() ustawiamy początkową wartość opisu na belce statusu.
Nie musimy tworzyć głównego menu ani belki statusu, gdyż zawierają się one w klasie QMainWindow. Wskaźniki do nich zwracają metody menuBar() oraz statusBar() (odpowiednio menu programu oraz belka statusu). Jest jeszcze ToolBar, który pozwala trzymać przyciski (chociaż można tam wcisnąć również zwykłe widgety, jak suwaki) ale o tej klasie powiem przy okazji zasobów programu. QActions (jak sama nazwa wskazuje ;)) pozwalają nam przypisać do nich różne akcje (funkcje) poprzez system sygnałów i slotów. Taką akcję możemy później dowolnie umieścić czy to w menu czy na ToolBarze. Na początku mogą się wydać mało intuicyjne, ale po kilku przykładach wszystko staje się jasne i zrozumiałe.

To na tyle, następnym razem wprowadzenie do Qt Creator. W razie pytań, wątpliwości lub jeżeli znaleźliście błąd piszcie w komentarzach, na e-mail lub Jabbera.

28 komentarzy do “Kurs Qt – część 1 – sygnały, sloty i własne widgety”

  1. Piotr, dnia 11 lipca 2010 o 22:55 napisał(a):

    bardzo fajny kurs. Brakuje tylko opisu, jak skompilować opisany kod. A tu można natrafić na dwie trudności. Po pierwsze trzeba poinformować kompilator o ścieżce do nagłówków ( -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui). Drugą, jest konieczność użycia moc-qt4 do każdego pliku z makrem Q_OBJECT, oraz dołączenie tak powstałego pliku w momencie linkowania

    P.S.
    tak, widziałem datę wpisu

  2. Matthew, dnia 12 lipca 2010 o 13:00 napisał(a):

    @Piotr: jak kompilować znajduje się we wstępie do kursu.

  3. Piotr, dnia 12 lipca 2010 o 13:24 napisał(a):

    po napisaniu komentarza zauważyłem.
    Jednak wolę napisać własnego makefile zamiast korzystać z qmake :P
    przynajmniej wiem dokładniej co się dzieje podczas kompilacji

  4. Matthew, dnia 12 lipca 2010 o 13:43 napisał(a):

    @Piotr: no cóż, jak chce Ci się marnować czas na coś co automat i tak zrobi to samo, ale znacznie szybciej. ;)

  5. godlark, dnia 25 lipca 2010 o 17:16 napisał(a):

    Trzeba się przyzwyczajać, że coraz więcej zadań będą za naś robić automaty – nawet w programowaniu :D
    Fajny ten Twój kurs, ale nie wiem czego u mnie, gdy są dużą litery w includach i brakuje końcówki „.h” to się nie chce skompilować.

    PS W mainwindow.hpp masz: #include

  6. dmx, dnia 12 września 2010 o 19:32 napisał(a):

    mam pytanie, czy konieczne jest łączenie poprzez connect? bo wykonalem prosty kalkulator i bez connect przypisalem poprostu ze jesli klikniety przycisk to wykonaj jakas akcje – czyli w tradycyjny sposob przez if z c++ , wiec kiedy wymagane jest uzywanie wylacznie slotow i sygnalow?

  7. Matthew, dnia 12 września 2010 o 19:38 napisał(a):

    @dmx: pokaż kod, bo nie ogarniam co masz na myśli.

  8. dmx, dnia 12 września 2010 o 20:11 napisał(a):

    1. zamiast connect(push_button,SIGNAL(clicked()),this,slot(obliczenia())

    zrobilem if(on_push_button_clicked())
    {
    obliczenia();
    }

    czyli bez uzywania tej funkcji connect, uzywania SIGNAL i SLOT, no i dziala. a moje pytanie dotyczy tego, czy lepiej, zebym zawsze uzywal connect?

    2. skoro nie trzeba dlugo czekac na odp (fajnie, ze mozna cie tu szybko napotkac, ze forum nie jest „martwe”) to wykorzystam to i zapytam tez o roznice miedzy qmainwindow, qwidget,qdialod – a mianowicie, rozpoczynajac projekt, najlepiej zaczac od qmainwindow? bo w niektorych przykladach zaczynasz od qwidget a efekt koncowy i tak jest taki sam (przynajmniej dla tych prostych przykladow)

    3. tworzac jakis obiekt, np okno lub widget – wpisujemy parent=0 (czyli ze nie ma rodzica) – a co wpisac, jesli tworzymy drugie okno, ktore chcemy wyswietlic na tym pierwszym, w parent= wpisac nazwe tego drugiego okna-dziecka?

    mam nadzieje, ze nie zawracam zbytnio glowy, ale wiem, ze troszke upierdliwy potrafie byc, do czasu, az nie poznam odpowiedzi na dreczace mnie pytanie lub az ktos mi nie wyjasni tego tak, abym zrozumial :) a ciesze sie, ze „dorwalem” kogos, kto ma pojecie o qt, bo niedawno zaczalem sie uczyc tej biblioteki

  9. dmx, dnia 12 września 2010 o 20:19 napisał(a):

    ok pytanie nr 3 juz chyba rozwiazalem, w kostruktorze piszemy THIS, prawda? (czasem tr(nazwa),this)

  10. Matthew, dnia 12 września 2010 o 20:23 napisał(a):

    @dmx: @1: nadal nie specjalnie wiem jak to zrobiłeś (cały kod!), ale co do funkcji on_cos_zdarzenie() to nadal to jest wykorzystywanie sygnałów/slotów (na tym się Qt opiera i przed tym nie uciekniesz), tylko że Qt dopuszcza właśnie używanie takich funkcji. W rzeczywistości są to sloty, tylko że łączone z sygnałami przez meta object compiler… ale nadal mi to nie pasuje do tego co zrobiłeś… weź wrzuć swój kod na jakąś wklejkę. A co do ogólnego pytania to moim zdaniem lepiej używać sygnałów/slotów bo są wygodniejsze i prostsze do późniejszej analizy.
    @2: (to nie jest forum, to jest blog!) QMainWindow i QDialog dziedziczą po QWidget i dodają do niego nowe funkcjonalności. A zaczynasz od tego co Ci bardziej jest potrzebne, dla prostych lepszy jest QWidget, dla wykorzystania menu + status bar lepiej użyć QMainWindow.
    @3: jeżeli to ma być drugie okno to nic nie wpisujesz.

  11. meff, dnia 6 października 2010 o 11:40 napisał(a):

    Witam, kurs kapitalnie się czyta, wszystko byłoby bardzo zrozumiałe gdyby nie jeden szczegół:
    To w jaki sposób opisujesz całość wskazuje, że kierujesz kurs do osób mających kiedyś coś wspólnego z programowaniem, a co z takimi co nie mają pojęcia cóż to u licha jest „#include” a z angielskim sa na bakier?
    Miałem nadzieję, że własnie trafiłem na stronkę gdzie można od samych podstaw się nauczyć Qt nawet starszemu już facetowi „hodowanym” na Turbo Pascalu :D
    Można liczyć na podstawy podstaw czy lepiej tłumaczyć w google anglojęzyczne www?:>

  12. Matthew, dnia 6 października 2010 o 15:49 napisał(a):

    @meff: nie mam jak, cała reszta (znaczy to co nie opisuję) to już jest C++ i średnio robić kurs C++ wewnątrz kursu Qt. Może, kiedyś, jak znajdę czas i chęci to skrobnę kurs C++0x, ale na razie się nie zapowiada.

  13. mihau87, dnia 14 października 2010 o 20:35 napisał(a):

    dobry tutorial. narazie sadze że dobrze mi idzie:P i zgadzam sie ze nie ma co tlumaczyc C/C++ bo to bez sensu.

    Docelowo chce zrobić w QT program ktory czyta z zewnatrz sygnal, pokazuje jego przebieg i go zapisuje w jakims pliku. Da radę? co musze sie jeszcze nauczyć?

  14. lmviii, dnia 7 listopada 2010 o 22:44 napisał(a):

    Te błędy w kodzie to specjalnie?

  15. Matthew, dnia 7 listopada 2010 o 23:04 napisał(a):

    @lmviii: które błędy w kodzie? Jak to pisałem to raczej działało i chyba też nikt się specjalnie nie skarżył.

  16. lmviii, dnia 7 listopada 2010 o 23:15 napisał(a):

    w trzecim kodzie od dołu brakuje nawiasu label = new QLabel(tr(„Smutna etykieta :(„, this); a w czwartym od góry jest #include .
    We wstępie kod też nie chciał mi się kompilować bo dodawane biblioteki(?) np. #include powinno być #include . albo tutaj trochę myślałem #include .

    Niby bzdury więc myślałem, że to takie pułapki, żeby nie kopiować bezmyślnie kodu, a przyznaje że trochę to zniechęca…

  17. lmviii, dnia 7 listopada 2010 o 23:19 napisał(a):

    no cóż nie można używać ostrych nawiasów więc jeszcze raz :(
    w trzecim kodzie od dołu brakuje nawiasu label = new QLabel(tr(„Smutna etykieta :(„, this); a w czwartym od góry jest #include QAainwindow.
    We wstępie kod też nie chciał mi się kompilować bo dodawane biblioteki(?) np. #include qapplication powinno być #include QApplication. albo tutaj trochę myślałem #include / qapplication qapplication.

    Niby bzdury więc myślałem, że to takie pułapki, żeby nie kopiować bezmyślnie kodu, a przyznaje że trochę to zniechęca…

  18. dKc, dnia 12 grudnia 2010 o 17:06 napisał(a):

    #ifndef MAINWINDOW_HPP
    #define MAINWINDOW_HPP

    #include //tu jest błąd :) Powinno być QMainWindow
    #include
    #include

  19. ewioru, dnia 30 grudnia 2010 o 17:21 napisał(a):

    finddialog.cpp: In member function ‘void FindDialog::createMenus()’:
    finddialog.cpp:85: error: ‘menuBar’ was not declared in this scope
    finddialog.cpp: In member function ‘void FindDialog::createStatusBar()’:
    finddialog.cpp:95: error: ‘statusBar’ was not declared in this scope
    make: *** [finddialog.o] Błąd 1

    Zrobilem mala modyfikacje i mam takie bledy

  20. zqt, dnia 7 lutego 2011 o 18:31 napisał(a):

    Witam po skompilowaniu dwóch ostatnich kodów programu dostaje takiego errora „error: collect2: ld returned 1 exit status”
    w czym jest problem ?

  21. bartek, dnia 4 marca 2011 o 00:58 napisał(a):

    zqt, dostaję dokładnie takiego samego errora :( kombinowałem z ustawieniami bibliotek, ale końcówka kompilacji wygląda tak:

    /usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/crt1.o: In function `_start’:
    (.text+0×20): undefined reference to `main’
    collect2: ld returned 1 exit status
    make: *** [2] Błąd 1

  22. OPX, dnia 20 marca 2011 o 19:53 napisał(a):

    bartek mam ten sam błąd.. Wie ktoś gdzie tkwi błąd w kodzie?

  23. langradus, dnia 4 kwietnia 2011 o 11:08 napisał(a):

    OPX, błąd twki najprawdopodobniej w tym, że do skompilowania potrzebujesz 3 plików, mainwindow.cpp, mainwindow.hpp i main.cpp ! ten ostatni jest na początku tekstu a potem modyfikowane są tylko 2 pozostałe pliki. U mnie pod ubuntu (x64) muszę dodatkowo zamieniać np. #include w #include , inaczej pisze, że nie ma takiego pliku :/ Ehh…

  24. langradus, dnia 4 kwietnia 2011 o 11:09 napisał(a):

    widzę, że nie prawidłowo wyświetla include, no więc muszę zamieniać duże znaki na małe i dodawać .h w nazwach nagłówków :/

  25. dysfunkcja, dnia 4 kwietnia 2011 o 22:08 napisał(a):

    dwa ostatnie kody sie nie kompiluja:
    undefined reference to `MainWindow::staticMetaObject’ in function ‘MainWindow::tr(char const*, char const*)’
    jakies pomysly?

  26. PeeR, dnia 17 kwietnia 2011 o 20:13 napisał(a):

    Mi wywalało to „collect2: ld returned 1 exit status” bo miałem plik nagłówkowy z rozszerzeniem *.h jak zmieniłem na *.hpp to i etykieta się zmienia, a nie chciała i menu działa :)

  27. WojtekC, dnia 1 maja 2011 o 15:36 napisał(a):

    Witam nie chce się tutaj za bardzo mądrzyć ponieważ jestem początkujący i dopiero zaczynam z Qt ale według mnie jest tutaj błąd w przykładnie 4.

    Mianowicie w linijce 7 i 8 jest tak :
    label = new QLabel (tr(„Smutna etykieta” ,this));
    label->setGeometry(5, 5, 150, 30);
    a tak się nie da gdy w mainwindow.hpp jest :
    Qlabel*label;
    Trzeba zmienić na QPushButton * label ;

    Albo ominąć to ‘tr’ przy wyświetlaniu ale wtedy to zwykły napis który się zmienia po wywołaniu funkcji a tak był przycisk który zmienia swoja nazwę.
    Nie wiem czy dobrze myślę.Nie chce jakoś urazić autora dla którego mam wielki szacunek za podjęcie się napisania tego kursu !!!
    :)

  28. Hase, dnia 12 maja 2011 o 15:06 napisał(a):

    A ja mam inny problem. Mianowicie, wszystko mi się pięknie kompiluje, natomiast nie pokazuje mi menu i paska statusu.

Zostaw komentarz

Subscribe without commenting