Grafikus Qt programok írása segédeszközök nélkül

Hasonló dokumentumok
Elemi alkalmazások fejlesztése III.

Elemi alkalmazások fejlesztése III.

Elemi alkalmazások fejlesztése III

Alkalmazások fejlesztése III. Qt 4 /C++ alapú grafikus alkalmazás Bevezetés I.

Egységes és objektumközpontú adatbázis-kezelés (2. rész)

Elemi alkalmazások fejlesztése III. A Qt assistant elindítása. Ajánlott ir odalom. A Qt assistant nyitó ablaka

QLabel *label = new Qlabel("Hello Qt!",0);

Tervezőeszközök, fejlesztőeszközök használata Qt alapú alkalmazásoknál. Saját vezérlő használata tervezőben (worldclocks)

Elemi alkalmazások fejlesztése III

Budapest, március. ELTE Informatikai Kar

Elemi alkalmazások fejlesztése IV. Adatbázis-kezelő GUI alkalmazás készítése 3. Összetett tábla karbantartása

2. Beadandó feladat dokumentáció

3. Osztályok II. Programozás II

QT Grafika Az alap alkalmazás felhasználói felülete

2. Beadandó feladat dokumentáció

A jobboldalon a pnlright egy Stacked Widget Állítsuk be az első lapot és nevezzük el pnldraw-ra:

3D-s számítógépes geometria és alakzatrekonstrukció

3D-s számítógépes geometria és alakzatrekonstrukció

Elemi alkalmazások fejlesztése III.

Grafikus felületek készítése 1.

Feladat. Tervezés és implementálás

Programozás C++ -ban

Grafikus Felhasználói Felületű (GUI) program készítése a QT Creatorral, illetve a Microsoft Visual Studio-val

Programozás C++ -ban 2007/4

Két csomag elemeiből lehet a felületet elkészíteni: awt: heavy weight komponensek; swing: light weight komponensek (időben később).

Eseménykezelés. Aszinkron kommunikáció

Programozás II gyakorlat. 4. Öröklődés

Elemi alkalmazások fejlesztése III.

MySql elindítása. Elemi alkalmazások fejlesztése IV. Feladat. Az alkalmazás adatbázisa

Elemi alkalmazások fejlesztése IV.

Programozás II gyakorlat. 6. Polimorfizmus

Osztályok. 4. gyakorlat

Osztály és objektum fogalma

Miután létrehoztuk, szeretnénk neki beszédesebb nevet adni. A név változtatásához a következőt kell tenni:

Programozás II. 4. Dr. Iványi Péter

Objektumok és osztályok. Az objektumorientált programozás alapjai. Rajzolás tollal, festés ecsettel. A koordinátarendszer

C++ programozási nyelv Konstruktorok-destruktorok

C programozási nyelv Pointerek, tömbök, pointer aritmetika

Programozás BMEKOKAA146. Dr. Bécsi Tamás 8. előadás

Qt rajzolás munkafüzet. Elemi Alkalmazások fejlesztése 3.

Bevezetés a Python programozási nyelvbe

Programozási technológia

Bevezetés a programozásba előadás: Öröklődés

if(_param.antialias) painter.setrenderhint(qpainter::antialiasing, true);

Bevezetés a programozásba II 1. gyakorlat. A grafikus könyvtár használata, alakzatok rajzolása

Java és web programozás

Johanyák Zsolt Csaba: Ugráló gomb oktatási segédlet Copyright 2008 Johanyák Zsolt Csaba

ESEMÉNY VEZÉRELT ALKALMAZÁSOK FEJLESZTÉSE I. Bevezetés. Készítette: Gregorics Tibor

3. Beadandó feladat dokumentáció

Grafikus felhasználói felületek. Dr. Szendrei Rudolf Informatikai Kar Eötvös Loránd Tudományegyetem. Programozási technológia I. Dr.

Swing GUI készítése NetBeans IDE segítségével

Programozás II gyakorlat. 8. Operátor túlterhelés

Elemi alkalmazások fejlesztése III.

Választó lekérdezés létrehozása

Tájékoztató. Használható segédeszköz: -

4. Öröklődés. Programozás II

Elemi alkalmazások fejlesztése

Dinamikus csatolású függvénykönyvtár készítése és használata Plugin-szerű betöltés Egyszeű C++ osztályok készítése

Bevezetés a programozásba Előadás: Tagfüggvények, osztály, objektum

Eseményvezérelt alkalmazások fejlesztése I 3. előadás. Dinamikus felületű alkalmazások. Giachetta Roberto

Broadcast Service Widget

Táblázatkezelés 2. - Adatbevitel, szerkesztés, formázás ADATBEVITEL. a., Begépelés

Grafikus felhasználói felület (GUI) létrehozása A GUI jelentése Egy egyszerű GUI mintaalkalmazás létrehozása

Kivételek, kivételkezelés a C++ nyelvben

OOP #14 (referencia-elv)

C++ referencia. Izsó Tamás február 17. A C++ nyelvben nagyon sok félreértés van a referenciával kapcsolatban. A Legyakoribb hibák:

Programozási technológia

C programozási nyelv

18. Szövegszerkesztők

C++ programozási nyelv

Programozás II. 3. gyakorlat Objektum Orientáltság C++-ban

Tájékoztató. Használható segédeszköz: -

Járműfedélzeti rendszerek II. 3. előadás Dr. Bécsi Tamás

Hardver modellezés SystemC-vel és SDL grafikus könyvtárral Visual Stúdió alatt

Bevezetés a programozásba Előadás: A const

Bevezetés a programozásba II. 8. Előadás: Osztályok, objektumok, osztályszintű metódusok

Dr. Pál László, Sapientia EMTE, Csíkszereda WEB PROGRAMOZÁS 2.ELŐADÁS. Objektumorientált programozás

Java programozási nyelv 8. rész Grafikus felhasználói felület

Elemi alkalmazások fejlesztése IV. Adatbáziskezel alkalmazás készítése QtDesignerben. Készítette: Szabóné Nacsa Rozália

Programozási alapismeretek 4.

Képfájlok beolvasása és megjelenítése

Java programozási nyelv 6. rész Java a gyakorlatban

Vizuális és eseményvezérelt programozás , II. félév BMF NIK

Dinamikus felületű alkalmazások. Stílusok, időzítő, képek

bool _freehand = false; QPoint _lastpoint; // ebben a pontban volt az utolsó rajzolásnál az egérmutató

Java és web programozás

Tájékoztató. Használható segédeszköz: -

Mobil informatika gyakorlat. 2. óra: NFC a gyakorlatban

Pelda öröklődésre: import java.io.*; import java.text.*; import java.util.*; import extra.*;

Adabáziselérés ODBC-n keresztül utasításokkal C#-ban

Java Programozás 5. Gy: Java alapok. Adatkezelő 1.rész

DKÜ ZRT. A Portál rendszer felületének általános bemutatása. Felhasználói útmutató. Támogatott böngészők. Felületek felépítése. Információs kártyák

Szövegek C++ -ban, a string osztály

QGIS tanfolyam (ver.2.0)

Eseményvezérelt alkalmazások fejlesztése I 10. előadás. Adatbázis-kezelés modell/nézet architektúrában. Giachetta Roberto

BME MOGI Gépészeti informatika 6.

Autodesk Inventor Professional New Default Standard.ipt

Eseményvezérelt alkalmazások fejlesztése I 8. előadás. Adatbázis-kezelés modell/nézet architektúrában

Alkalmazások fejlesztése III. Qt 4 /C++ alapú MDI alkalmazás: Számlakészítő program 3/3

Átírás:

Grafikus Qt programok írása segédeszközök nélkül Grafikus felületű Qt programokat ahogy láttuk, készíthetünk egy egyszerű szövegszerkesztővel is, bár a Qt jó támogatást ad a grafikus felület grafikus tervezésére a QtCreator és a QtDesigner segítségével. Ezzel azért foglalkozunk, hogy megismerjük a Qt grafikus elemek jellegzetességeit. A grafika egy ún. Grafikus Felhasználói Felületen (Graphical User Interface GUI) jelenik meg. Ilyen van a Windows-ban a Linuxban, a Mac-eken és a mobil eszközökön. Az eseményhurok (event loop) A QApplication::exec() az esemény hurok, vagy ciklus. Minden Qt-s grafikus program tartalmaz egy ilyet. Ezt többnyire egy külön fájlba (pl. main.cpp) helyezzük el A legegyszerűbb esetben ez a fájl így néz ki: #include "saját_include_fájlunk.h" #include <QApplication> int main(int argc, char *argv[]) QApplication a(argc, argv); AlapWidgetünk w; // pl. a QDialog-ból leszármaztatott widget, de lehet // akár egy QLabel is w.show(); // kirajzolja az AlapWidget-et, de az még nem jelenik meg // csak amikor feldolgozzuk a kirajzolási üzeneteket return a.exec(); // itt az eseményhurokban Az AlapWidgetünk declarációja a saját_include_fájlunk.h fájlban van. Az eseményhurok feladata az operációs rendszerből származó felhasználó, vagy programok által generált események (pl. gombnyomás, egérműveletek,érintés, kirajzolás) kezelése. A Qt események olyan objektumok, amelyek vagy az alkalmazáson belüli történéseket, vagy olyan külső történéseket (pl gombnyomás, egérmutató mozgatás) reprezentálnak, amelyekről az alkalmazásnak tudnia kell. Amikor egy esemény történik a Qt rendszer létrehoz egy azt reprezentáló objektumot és elküldi azt a programunk valamelyik objektumának. Háromféle esemény van: spontán események Az ablakkezelő rendszer generálja. A rendszer sorba állítja ezeket, ahonnan egymás után kerülnek az eseményhurokba POST-olt események Qt, vagy az alkalmazás generálja ezeket. A Qt állítja ezeket sorba és helyezi be egymás után az esemény ciklusba feldolgozásra Közvetlen (SENT) események Qt, vagy az alkalmazás generálja ezeket és közvetlenül a fogadó objektum-nak küldjük el, ez nem kerül be a sorba.

Az eseményeket leszármaztatott osztályokban magunk is lekezelhetjük. Ha pl. azt akarjuk, hogy egy címke méretezésével annak betűmérete is nőjön, akkor a QLabel resizeevent függvényét kell átdefiniáljuk. Ehhez a QLabel-ből leszármaztatunk egy másik objektumot, amelyben lekezeljük a méretváltoztatást és azt használjuk a QLabel helyett: Class QMyLabel : public QLabel Q_OBJECT void resizeevent(qresizeevent *event) QFont f = font(); f.setpointsizef( f.pointsize()f * (event->oldsize().height()/size().height() ); setfont(f);

Widget-ek Minden grafikus Qt program ún. widget-eken alapul. Ezek megjeleníthető grafikus komponenseket 1 (pl. gombok, cimkék, szövegbeviteli mezők) tartalmazó egyszerű, vagy összetett objektumok. Szerepelhetnek önállóan a képernyőn ahogy azt láttuk, de más widgetek részeként is. A legtöbb widget valamely más widgethez, a szülőjéhez (párent) tartozik, abban jelenik meg. Minden widget a QWidget-ből van leszármaztatva, ami maga viszont a QObject-ből. A QObject-nek sok hasznos tulajdonsága van, amit a widgetek-ben is használhatunk. Egy különösen hasznos tulajdonsága, hogy tetszőleges számú és nevű saját mezőt (property) adhatunk hozzá. Amikor leszármaztatunk egy widget-et egy másikból az osztály deklaráció elejére mindig be kell írni a Q_OBJECT makrót, különben nem lesz érvényes widget-ünk! Az első saját grafikus objektum, amit megjelenítünk a képernyőn rendszerint vagy a QMainWindow, vagy a QDialog widgetből leszármaztatott saját widget-ünk. Azért kell ezekből leszármaztatni saját widget-eket, hogy hozzájuk adhassuk a saját widget-jeinket. A widget-ek méretét és a befoglaló widget-hez (parent), vagy ha ilyen nincs - a képernyőhöz képesti helyzetét a geometriája (lekérdezése: QRect rect = widget.geometry(), beállítása widget.setgeometry( rect)) adja meg. A rect tartalma: x, y, szélesség, magasság, az x,y koordináták a szülő bal felső sarkához képest értendőek 2. Egyebek között minden widgethez tartozik még egy minimális és egy maximális méret (szélesség, magasság), egy betű fajta (font név, méret, stílus), valamint egy stíluslap (style sheet). Ha a minimális és maximális méretek megegyeznek a widget nem méretezhető át. Ez jól használható pl. a fő, vagy dialógus ablakoknál. Példaként készítsünk egy jegyzetfüzet programot, amibe szabadon írhatunk szövegeket! A jegyzetfüzet így fog kinézni: 1 Ha a szülő widget nem látható, akkor természetesen a benne levők sem, de a benne levő widget-eket el is rejthetjük. 2 Az x tengely vízszintesen jobb, az y tengely függőlegesen lefelé mutat.

A tervezésnél kétféleképpen járhatunk el. 1. gondosan megtervezzük kockás papíron és minden méretet manuálisan állítunk be. Ha azt szeretnénk azonban, hogy az ablak mérete változtatható legyen és ekkor a jegyzetfüzet szerkesztő része az aktuális ablakkal nőjön, vagy csökkenjen, akkor ez nem igazán jó út. Akkor is gond lehet, ha a képernyőfelbontás, vagy a képernyő betűmérete megváltozik. 2. Megvalósítjuk az elrendezést úgy, hogy a szükséges méreteket a rendszer számolja ki nekünk. Ehhez elrendezéseket (layout-okat) használhatunk. Az elrendezések nem widget-ek, mert maguk nem jelennek meg a képernyőn. Mi a 2. utat fogjuk követni. Van vízszintes (horizontal), függőleges (vertical), rács (grid) és nyomtatvány (form) elrendezés. Az utolsóban az elemeket páronként sorokba rendezi el a Qt. Minden sorba két elem (pl. szöveg és beviteli mező) kerül. Bármelyik elrendezés esetén az ablak méretének változtatásával az elemek mérete is változik. Első ránézésre a függőleges elrendezést választanánk, kezdjük tehát azzal!

Mindenekelőtt hozzunk létre egy alkönytárat a saját könyvtárunkban. Legyen a neve npad! Hozzuk létre a következő fájlokat: main.cpp, notepad.h, notepad.cpp: Main.cpp #include "notepad.h" #include <QApplication> int main(int argc, char *argv[]) QApplication a(argc, argv); Notepad w; // AlapWidgetünk most a Notepad a notepad.h-ból w.show(); return a.exec(); Notepad.h A fájl ezzel kezdődik: ifndef NOTEPAD_H #define NOTEPAD_H Ezzel a két sorral elérjük, hogy a header csak egyszer kerüljön feldolgozásra. A záró #endif a fájl legvégére kerül. Becsatoljuk az összes widget include fájlját: #include <QMainWindow> #include <QtWidgets/QPushButton> #include <QtWidgets/QTextEdit> #include <QtWidgets/QWidget> #include <QtWidgets/QVBoxLayout> A QVBoxLayout tartalmazza a függőleges elrendezést. Minden widget az Ui namespace része, ezért a mi új widgetünk is oda tartozik: namespace Ui class Notepad; Amikor egy widgetet származtatunk le egy másikból, mindig meg kell mondani, hogy az a QObject leszármazottja. Ezt a Q_OBJECT makróval tesszük meg. class Notepad : public QMainWindow Q_OBJECT A nyilvános részbe csak a konstruktor és a destruktor kerül. A widget-ek (és a QMainWindow is egy widget) konstruktorában adjuk meg azt a szülő (parent) widget et, aminek az ablakába

ez a widget megjelenik majd. Ez a mi esetünkben egy nullptr 3 lesz, mert az ablakunk a fő ablak.. public: explicit Notepad(QWidget *parent = 0); ~Notepad(); A private részbe kerülnek a widget-eink és a grafikát felépítő függvény: private: A QMainWindow-nak szüksége van egy speciális widgetre, ami tulajdonképpen az összes elem szülője lesz. Ez a centralwidget. A többi widget: QWidget *centralwidget; QBoxLayout *vertlayout; QTextEdit *edtnote; QPushButton *btnclose; Az ablakot fel kell építeni, hozzá kell adjuk az összes widget-et. Ezt a void setupui(); függvény végzi majd el. SIGNAL-ok és SLOT-ok Mikor a bezárás gombot megnyomjuk az ablaknak be kell záródnia. A gombnyomás is egy esemény, és azt szeretnénk, hogy ezt az eseményt a fő ablak kapja meg. Két widget egymással a signals and slots mechanizmuson keresztül beszélget. Az egyes signal-okat és slot-okat explicit módon a connect() függvénnyel kapcsoljuk majd össze. Jelen esetben azt akarjuk, hogy amikor a btnclose gombra kattintunk 4, akkor a fő ablaknak egy függvénye (hívjuk pl. btncloseclicked()-nek) hívódjon meg amivel az bezárja magát 5. Ehhez a btncloseclicked() függvényt a fő ablak fogadóhelyévé (slot-jává) kell tegyük. 3 A nullptr a C++11-ben bevezetett kulcsszó. Jelentése megegyezik a korábbi NULL define-éval. 4 Vagy billentyűzettel benyomták, amit ebben a példában nem valósítunk meg. 5 Tehát nem a gomb zárja be az ablakot, hanem az saját magát.

Ehhez ezt kell beírjuk: private slots: void btncloseclicked() close(); A slots kulcsszót a C++ fordító program nem látja, az egy Qt kiegészítés, amire most semmi szükség nem lenne, de szokjuk meg, hogy oda írjuk, mert a későbbiekben használni fogjuk. Zárjuk be az osztálydeklarációt és a fájlt! ; #endif // NOTEPAD_H A következő fájl a notepad.cpp Notepad.cpp Ez a header fájl beolvasásával kezdődik, amit a konstruktor követ:. include "notepad.h" Notepad::Notepad(QWidget *parent) : QMainWindow(parent) setupui(); A konstruktorban felépítjük a felhasználói felületet. Mint látni fogjuk az egyes widget-eket a new operátorral hozzuk létre, ezért azt hinnénk, hogy kilépés előtt fel is kell szabadítsuk őket, de erre nincs szükség. A szülő (parent) widgetek gondoskodnak minderről 6. A destruktor ezért most nem csinál semmit: Notepad::~Notepad() A felhasználói felület elkészítését a setupui() függvény végzi: void Notepad::setupUi() Állítsuk be az ablak (kezdő) méretét 400 x 300 pixelre: resize(400, 300); 6 Természetesen a new-val dinamikusan létrehozott saját (nem QTs) objektumainkat, illetve azokat a Qts objektumokat, amiket nem adunk hozzá más QTs objektumokhoz nekünk kell felszabadítanunk!

Az ablak pozícióját nem adjuk meg, azt az operációs rendszer fogja meghatározni. Közvetlenül egy QMainWindow-hoz (tehát a belőle leszármaztatott Notpead-hez sem) nem adhatunk hozzá widge-eket, ezért ehhez szükségünk lesz egy speciális szerű widget-re. Ezt nevezzük mondjuk centralwidget-nek, mert majd a setcentralwidget() függvénnyel adjuk hozzá a Notepad-hez. centralwidget = new QWidget(this); Beállítjuk a centralwidgettet az ablakhoz, ezzel érjük el, hogy a widget-jeink megjelenhessenek: setcentralwidget(centralwidget); Minden más widget a centralwidet-re kerül, ezért a centralwidget hez kapcsoljuk a layoutot, amelyet úgy állítunk be, hogy legyen egy 11 pixeles margója az elemek körül és az elemek egymástól 6 pixelre legyenek: vertlayout = new QVBoxLayout(centralWidget); vertlayout->setspacing(6); vertlayout->setcontentsmargins(11, 11, 11, 11); Elkezdjük hozzáadni a widget-eket. Minden widget a fő ablak centralwidget-ében jelenik meg, ezért mindegyik szülője az lesz. De a widgetet a layouthoz is hozzá kell adni, mert az fogja a méretét és a helyét meghatározni. A layout viszont nem lesz szülője a widgeteknek 7. Minden widget létrehozásakor megadjuk a szülőjét és, hozzácsatoljuk a layouthoz: edtnote = new QTextEdit(centralWidget); vertlayout->addwidget(edtnote); btnclose = new QPushButton(centralWidget); btnclose->settext("&bez\303\241r\303\241s"); // &Bezárás UTF8 kódolással vertlayout->addwidget(btnclose); Ezután megmondjuk az ablaknak, hogy a gomb benyomására zárja be magát. A connect függvénnyel összekapcsoljuk egy adott widget (itt btnclose) valamelyik signal-ját (itt clicked() ) a fogadó widget (Notepad-tehát ez az objektum) adott slot-jával (btncloseclicked()) A signal elküldését megcsinálja a gomb. Az lenne jó, ha ezt írhatnánk: connect( btnclose, clicked, this, btncloseclicked ), de ezt a C++ szabályai nem engedik. A connect függvény mutatókat vár, de sem a QPushButton::clicked() sem a btncloseclicked() mindkettő void - nem ad ilyet vissza. Még azt sem írhatnánk, hogy 7 Egyrészt a layout nem widget, másrészt egy widget-nek csak egy szülője lehet.

QPushButton::clicked, ugyanis a clicked() nem egy nem sztatikus függvénye a nyomógombnak, ezért nem lehet meghívni konkrét objektum nélkül. A függvény törzsére mutató mutató azonban megadható, hiszen a függvények minden objektumra ugyanazok 8 : connect( btnclose, &QPushButton::clicked, this, &Notepad::btnCloseClicked ); // setupui Most már csak a projekt és Makefile-t kell elkészíteni: Npad.pro és Makefile Qmake-qt5 -project Ismét bele kell javítsunk az npad.pro fájlba. Adjuk hozzá a következő két sort: QT += core gui widgets QMAKE_CXXFLAGS += -std=c++11 A többi már egyszerű: qmake-qt5 make Futtassuk a programot:./npad&. Ez nem egészen azt produkálja, amit vártunk: Az ablak ugyan méretezhető és a gomb magassága sem változik, de a gomb az egész ablak szélességét elfoglalja. Ez a függőleges elrendezés tulajdonsága. Ahhoz, hogy a gomb a jobb oldalon maradjon és a mérete se változzon egyfelől a függőleges elrendezést rácsosra kell cseréljük, másfelől használnunk kell egy láthatatlan elemet a vízszintes térkitöltőt (horizontal 8 Emlékezzünk arra, hogy minden nem sztatikus tagfüggvény vár egy, az aktuális objektumra mutató mutatót (pointert) mint rejtett paramétert. A connect-re később más lehetőségeket is megismerünk majd. Ezekről akkor fogunk beszélni, amikor a QtCreatort/QtDesigner-t használjuk.

spacer). Ez egy olyan elem, ami addig nyúlik, ameddig szükséges és ezért az ablak méretének változásával a többi elem méretét a layout nem fogja megváltoztatni 9. A változtatások: A notepad.h-ban az #include <QtWidgets/QVBoxLayout> sort cseréljük le #include <QtWidgets/QGridLayout> -ra és a QVBoxLayout-ot cseréljük le QGridLayout-ra: QGridLayout *gridlayout; a QPushButton elé pedig szúrjuk be ezt: QSpacerItem *horizontalspacer; A notepad.cpp-ben a setupui()-t cseréljük le a következőre: void Notepad::setupUi() resize(400, 300); centralwidget = new QWidget(this); gridlayout = new QGridLayout(centralWidget); gridlayout->setspacing(6); gridlayout->setcontentsmargins(11, 11, 11, 11); edtnote = new QTextEdit(centralWidget); gridlayout->addwidget(edtnote, 0, 0, 1, 2); horizontalspacer = new QSpacerItem(295, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); gridlayout->additem(horizontalspacer, 1, 0, 1, 1); btnclose = new QPushButton(centralWidget); btnclose->settext("&bez\303\241r\303\241s"); gridlayout->addwidget(btnclose, 1, 1, 1, 1); setcentralwidget(centralwidget); connect( btnclose, &QPushButton::clicked, this, &Notepad::btnCloseClicked ); 9 Természetesen van függőleges térkitöltő (vertical spacer) is. Sok esetben azonban a kívánt elrendezés még ezekkel sem érhető el, ilyenkor plusz widget-eket is kell használnunk.

Látható, hogy a rácsos elrendezésben az addwidget() hívásokban újabb szám paraméterek jelentek meg. A szintaxis a következő: QGridLayout::AddWidget(QWidget *widget, int fromrow, int fromcolumn, int rowspan, int columnspan, Qt::Alignment alignment = Qt::Alignment()) Az első két paraméter az elem kezdő oszlopa és sora a rácsban, a második kettő pedig, hogy hány sorra, ill. oszlopra terjed ki az elem. Az utolsó paramétert alapértelmezettnek hagyjuk. Már csak egy make parancs és az npad program készen van és futtattható.

A teljes program main.cpp #include "notepad.h" #include <QApplication> int main(int argc, char *argv[]) QApplication a(argc, argv); Notepad w; w.show(); return a.exec(); notepad.h #ifndef NOTEPAD_H #define NOTEPAD_H #include <QtCore/QVariant> #include <QtWidgets/QGridLayout> #include <QtWidgets/QMainWindow> #include <QtWidgets/QPushButton> #include <QtWidgets/QSpacerItem> #include <QtWidgets/QTextEdit> #include <QtWidgets/QWidget> #include <QMainWindow> namespace Ui class Notepad; class Notepad : public QMainWindow Q_OBJECT public: explicit Notepad(QWidget *parent = 0); ~Notepad(); private: QWidget *centralwidget; QGridLayout *gridlayout; QTextEdit *edtnote; QSpacerItem *horizontalspacer; QPushButton *btnclose; void setupui(); private: void btncloseclicked() close(); ; #endif // NOTEPAD_H notepad.cpp #include "notepad.h"

Notepad::Notepad(QWidget *parent) : QMainWindow(parent) setupui(); Notepad::~Notepad() void Notepad::setupUi() resize(400, 300); centralwidget = new QWidget(this); setcentralwidget(centralwidget); gridlayout = new QGridLayout(centralWidget); gridlayout->setspacing(6); gridlayout->setcontentsmargins(11, 11, 11, 11); edtnote = new QTextEdit(centralWidget); gridlayout->addwidget(edtnote, 0, 0, 1, 2); horizontalspacer = new QSpacerItem(295, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); gridlayout->additem(horizontalspacer, 1, 0, 1, 1); btnclose = new QPushButton(centralWidget); btnclose->settext("&bez\303\241r\303\241s"); gridlayout->addwidget(btnclose, 1, 1, 1, 1); //if (!connect(btnclose, SIGNAL(clicked()), this, SLOT(btnCloseClicked()))) // // edtnote->append("no valid connection to button"); // if(!connect( btnclose, &QPushButton::clicked,this, &Notepad::btnCloseClicked)) edtnote->append("no valid connection to button"); // setupui notepad.pro ###################################################################### # Automatically generated by qmake (3.0) V szept. 18 14:08:55 2016 # javításokkal ###################################################################### TEMPLATE = app TARGET = npad INCLUDEPATH +=. # Input HEADERS += notepad.h SOURCES += main.cpp notepad.cpp QT += core gui widgets