...
- Ensimmäisessä tehtävässä teemme QT Creatorin graaffisella editorilla Dialogin, johon viemme kaksi widgetiä eli graaffista elementtiä. Eli tee Qt Creatorilla dialogi-sovellus seuraavasti:
valitse:
File-> New file or project
-> Qt Widget Project
-> Qt Gui Application
-> Anna projektin nimi ja tallennuskansio
-> valitse QMainWindow tilalle QDialog
->aja > aja loput oletusasetuksilla läpi.
Valitse vasemmalta alhaalta Debug build. Käännä ja testaa sovellus painikkeella F5, ohjelman pitäisi käynnistyä ja (tyhjän) dialogin piirtyä ruudulle. Tutustu koodiin ja etsi sieltä pääohjelma, muodostin = constructor sekä hajotin = destructor.
Nimeä em. funktiot koodiin, kopioi koodi ja lähetä se tuubin kautta tehtävän 1. vastauksena. Älä käytä liitetiedostoa, vaan maalaa koodi vastausikkunaan.
***********
- Laita breakpoint kaikkiin lähdekoodiin funktioihin aaltosulkujen väliin; laita yksi break point pääohjelmaan (main.cpp) ennen dialogin muodostinta ja yksi show funktion eteen-funktiokutsun eteen (mainwindow.cpp).
Breakpointin voit asettaa viemällä hiiren kursorin rivinumeroinnin vasemmalle puolelle ja klikkaamalla siellä olevaa tyhjää aluetta. Aja F5:llä kaikki breakpointit läpi. Selvitä funktioiden ajojärjestys ja vastaa se tuubiin.
- Jatka edellistä tehtävää seuraavasti. Laita dialogiin liukupalkki (Horizontal tai Vertical Slider) ja "lcd"-näyttö QLCDNumber.
Johda liukupalkin signaali (valueChanged) "lcd"-näytön slotiin (display) signal-slot tilassa (F4).
Tee graafisella editorilla kytkennät "widgetien" välille. Testaa sovellus.
Laita graafisessa editorissa edellisen liukupalkin alarajaksi -100 ja ylärajaksi 100. Testaa. Ota Snipping Toolilla kuva dialogista siten, että liitynnät näkyvät ja laita se tuubiin.
- Vie liukupalkin arvo edistymispalkin " QProgressBar " arvoksi. Ota Snipping Toolilla kuva dialogista siten, että liitynnät näkyvät ja laita se tuubiin.
Tee uusi projekti tehtävälle no 1 ja laite siihen edellä olevat widgetit. Kytke connect-funktion avulla eli lisää Dialogin muodostimeen connect.... Alla esimerkki connect-funktion käytöstä:
Code Block language cpp collapse true //alla olevasta koodista löydät viisi ensimmäistä riviä valmiina Dialogi.cpp tiedostosta, lisää connect funktio niiden perään //kuten tässäkin on tehty Dialogi::Dialogi(QWidget *parent) : QDialog(parent), ui(new Ui::Dialogi) { ui->setupUi(this);//tämä on jo tehty puolestasi automaattisesti //yhdistetaan signaalit ja slotit, valitse komponentit valikosta ALÄ KOPIOI ettei mene suteen //ui-> tarkoittaa sitä, että komponentti on käyttöliittymässä ja ui-> on osoite käyttöliittymään connect(ui->horizontalSlider,SIGNAL(valueChanged(int)),ui->lcd,SLOT(display(int))); ....
- Tee Dialog sovellus, jossa on Date Time Edit ja Calender widgetit. Kytke ne yhteen siten, että muutettaessa kumpaa tahansa, muuttuu myös toisen asetus. a.Tee graafisella editorilla signal - slot -liityntä (eli nuolilla) . b Ota nuolet pois ja tee liityntä connect-funktiolla. Huom. lisää dialog.h tiedostoon #include <QDate> muiden include komentojen alle.
- Tee Dialog sovellus , jossa Dial valikon arvo menee lcd-näyttöön. a.Tee graafisella editorilla signal - slot -liityntä (eli nuolilla) ja testaa, ota kuva liitynnöistä ja lähetä vastaus tuubilla. b Tee liityntä connect-funktiolla.
Tässä tehtävässä viet haluamasi tekstin labeliin eli tekstinäyttöön ruudulla, kun painat dialogissa olevaa nappulaa. Eli tee dialogi, johon luot graafisessa editorissa painonapin ja labelin. Nimeä nappi ja label siten, että muistat niiden merkityksen. Tee .h-tiedostoon oma slotin esittely seuraavasti eli avaa Dialog.h ja aaltosulkeiden sisälle ennen lopettavaa sulkua lisää alla oleva teksti. Jos ei muistu mieleen slotit ja signaalit, niin katso täältä: ohjeita signaaleista ja sloteista
Code Block language cpp collapse true ... public slots: void nayta(); ...
Tee slotin toteutustiedostoon Dialog.cpp. Lisää tiedostoon funktio, joka näyttää tekstin label ruudulla.
Code Block language cpp collapse true //tämän lisäät Dialog.cpp tiedoston loppuun void Dialog::nayta() { //laita ui-> jos olet tehnyt labelin dialogiin QString Tekstia;//tämä on muuttuja joka tallettaa merkkijonoja Tekstia="juttuja"; ui->label->setText(Tekstia);//tällä laitat tekstin labeliin }
Liitä napin signaali omaan slotiisi. Tee tämä dialogin muodostimessa (slot on nyt Dialogissa).
Code Block language cpp collapse true ui->setupUi(this);//tämä on jo tullut automaattisesti //yhdistetaan signaalit ja slotit, valitse komponentit valikosta ÄLÄ KOPIOI ettei mene suteen //this alla tarkoittaa, että vastaanottaja on tämän tiedoston (luokan) slot connect(ui->Nappi,SIGNAL(clicked()),this,SLOT(nayta()));
Tässä tehtävässä on tarkoituksena tehdä sekuntikello, jonka voi käynnistää, laittaa tauolle, käynnistää uudelleen ja pysäyttää nappien avulla. Kello toteutetaan QTimer-luokan avulla (tutustu QTimer linkin alta löytyvään tekstiin!!!). Tee dialogiin painikkeet start, pause, jatka, stop ja nollaus. Tee painikkeille slotit (go to slot) sekä vielä lcd-näyttö kellon arvoa varten. Tee QTimer timer; muuttuja Dialog.h tiedostoon alla olevan esimerkin mukaisesti.
Code Block language cpp collapse true #include <QDialog> // tämä on jo tehty puolestasi eli lisää alla oleva rivi #include <QTimer> //lisää tämä, tähänhän jo tutustuit QTimer helpissä ... lisää seuraavat muuttujat luokan esittelyyn Dialog.h tiedostossa ~Dialog();// tämä on jo tehty puolestasi automaattisesti, lisää alla olevat muuttujat QTimer timer;//ajastin ajan laskentaa varten, tämä rivi sinun täytyy lisätä int laskuri;//laskuri joka laskee ajastimen timeout eli kertoja jotka ajastin on käynyt loppuun ... private slots: void on_StopTimer_clicked();//tämä tuli automaattiseti kun teit Stop painikkeen ja sille slotin "go to slot" määrittelyllä void on_StartTimer_clicked();//ja tuli kanssa samalla tavoin void PaivitaNaytto();//tämän joudut tekemään itse ja vastaavan funktion Dialog.cpp tiedostoon };
Nyt timer on muuttuja, joka sisältää ajastimen. Esimerkiksi timer.start(1000) käynnistää ajastimen yhden sekunnin resoluutiolla. Ajastimen timeout signaalin joudut kiinnittämään itse tekemääsi slotiin PavitaNaytto seuraavasti Dialogin muodostimessa, muistathan että muodostin on se jossa luokan nimi on sama kuin funktion nimi.
Code Block language cpp ui->setupUi(this);//tämä on jo Dialogin muodotimessa //tämän liitynnän ajastimen timeout signaalista ja PaivitaNaytto //& merkki tarkoitaa siirtymistä muuttujasta osoitteeseen //eli timer on muuttuja &timer on muuttujan osoite connect(&timer,SIGNAL(timeout()),this,SLOT(PaivitaNaytto()));
Ja sitten vielä funktioiden sisällöt Dialog.cpp tiedostoon. Muistathan, että teit funktioiden rungot "go to slot" mekanismilla.
Code Block collapse true void Dialog::on_StartTimer_clicked()//tämän olet tehnyt "go to slot" määrittelyllä { timer.start(100); laskuri=0; } void Dialog::on_StopTimer_clicked()//tämän olet tehnyt "go to slot" määrittelyllä { timer.stop(); } //ja tähän ilmestyy loppujen painikkeiden slotit, kun teet ne "go to slot" määrittelyllä //ajetaan läpi timeoutista eli tämän teet itse void Dialog::PaivitaNaytto() { laskuri++; ui->lcdNumber->display(laskuri); }
Lisää vielä sisällöt funktioille Jatka ja Pause sekä tee kaikki tarvittavat funktiot ja testaa ohjelma.
Muuta edellisen tehtävän kelloa siten, että tarkkuus on 0.01 sekuntia. Eli joudut muuttamaan timerin start-asetusta. kts. QTimer help. Sijoita laskuri double tyypin muuttujaan
Code Block language cpp double apu=laskuri;
ja jaa apu 100:lla (kokeile lukuja 100 ja 100.0, miten ne eroaa?) sekä sijoita arvo lcd-näyttöön.
Muuta edellisen tehtävää siten, että nyt on vain painonapit start/pause, stop ja nollaus. Eli muuta start/pause-napin tekstiä sen mukaan onko ajastin tilassa käynnissä/pysäytettynä. Huom! tarvitset luokkaan muuttujan, jossa pidät yllä laskurin tilaa.
Code Block language cpp collapse true void Dialog::on_StartTimer_clicked() { QString TekstiPainikkeessa; if(FlipFlop==false)//FlipFlop on bool tyypin muuttuja, joka on esiteltävä luokkamäärittelyssä Dialog.h bool FlipFlop; { timer.start(100); laskuri=0;//tämä rivi kannattanee siirtää muodostimeen, jos et muista mikä on muodostin niin tarkasta tehtävästä kaksi FlipFlop=true; //esittele tämä muuttuja Dialog.h tiedostossa bool FlipFlop; ja aseta //FlipFlop asetetaan tilaan false Dialogin muodostimessa (muodostin kts teht. 2) TekstiPainikkeessa="Pause"; ui->StartTimer->setText(TekstiPainikkeessa); } else { timer.stop(); FlipFlop=false; TekstiPainikkeessa="Start"; ui->StartTimer->setText(TekstiPainikkeessa); } }
Muuta edellistä tehtävää siten, että voit muuttaa tarkkuutta vaikka spinBox"widgetillä". Muistat tietysti määritellä spinBoxin graafisessa käyttöliittymässä.
Code Block language cpp collapse true void Dialog::on_StartTimer_clicked() { ui->spinBox->setMinimum(0); ui->spinBox->setMaximum(2); int desimaalit = ui->spinBox->value(); if(desimaalit==0) aikaResoluutio=1000;//esittele aikaresoluutio .h tiedostossa if(desimaalit==1) aikaResoluutio=100; if(desimaalit==2) aikaResoluutio=10; timer.start(aikaResoluutio); laskuri=0; ....
Lisäksi joudut asettamaan päivitysfunktioon ehdon, jolla asetat laskurin lisäykseksi 1, jos aikaresoluutio on 1000 ja 0.1 jos aikaresoluutio on 100 jne.
Tässä tehtävässä opetellaan muuttujan ja osoittimen eroa. Joku fiksu jo varmaan ihmetteli, että miksi ajastin esiteltiin connect funktiossa näin connect(&timer.... Tämä johtuu siitä, connect vaatii lähteen ja kohteen osoitteen sulkujen sisälle. Muuttujan osoite saadaan & merkillä, mutta voimme esitellä muuttujan jo valmiiksi osoitteena. Tällöin ohjelman syntaksi muuttuu ja timer muuttujaa ei enää käytetäkään esimerkiksi timer.start(100); vaan timer->start(100). Tässä tapauksessa timer muuttujalle täytyy myös varata muistia ja esittely tehdään toisella tavoin.
Code Block language cpp collapse true class Dialog : public QDialog { Q_OBJECT public: Dialog(QWidget *parent = 0); ~Dialog(); //kun timer muuttujan eteen laitetaan * se on osoitin eikä muuttuja QTimer *timer; //laskuri joka laskee ajastimen timeout eli kertoja jotka ajastin on käynyt loppuun int laskuri;
Lisäksi joudutaan tekemään Dialog.cpp tiedostossa muodostimeen lisäys muistinvarausta varten.Code Block language cpp collapse true Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); timer = new QTimer();// nyt muisti on varattu ja timer osoitin on käytettävissä //eli nyt voidaan & merkki ottaa timer muuttujan edestä pois //this on muuten myös osoitin, kuten huomaat senkään edessä ei ole & merkkiä connect(timer,SIGNAL(timeout()),this,SLOT(PaivitaNaytto())); FlipFlop=false; }
Lisäksi joudut käymään läpi kaikki kohdat, joissa olet käyttänyt timer muuttujaa ja muuttamaan pisteet "nuoliksi" ("->").
- a.Tee ohjelma, joka sisältää painonapin "PushButton" ja viesti-ikkunan "MessageBox". Kun painetaan nappia, ohjelma näyttää viestiruudulla "MessageBox" viestin "nappia painettu". b. Vie edellisen tehtävän teksti QLabel ikkunaan.
c. Vie edellisen tehtävän teksti QLineEdit ikkunaan d. Tutustu Qt:n QDebug luokkaan ja tulosta sen avulla edellisen tehtävän teksti komentoikkunaan.
- a. Tee ohjelma, joka ilmoittaa millä välillä annettu luku on. Laita annettu arvo lineEdit "ikkunaan" ja nappia "pushButton" painettaessa testaa if-lauseella arvoalue. Aseta "RadioButton"in (yhden kolmesta) arvo osoittamaan arvoväliä 0...10, 11...100 tai >100. b. Tee edellinen tehtävä siten, että painonapilla vaihdat tekstikentän validaattoria "lennosta" ja laitat samalla vastaavan radioButtonin osoittamaan sallittua lukualuetta.
- Tee Radio button valikko kolmella painikkeella dialogiin. Lisää teksiruutu, jossa kerrot mitä painikkeista on painettu.
- Tee laskin, jossa on oikealla plus-, miinus-, kerto- ja jakopainikkeet. Vasemmalla on kolme teksti-ikkunaa, kahden ylimmän ruudun tulos laitetaan alimpaan ruutuun riippuen painettavasta napista. Lisää tekstikenttiin validaattorit, ettei numerokenttiin voi syöttää kirjaimia kts. mallia esimerkistä double validator.
- Tee säännöllisiä lauseita (regular expression) käyttäen syöttruutu, johon voi syöttää vain "Excel" solun arvoja, joissa on yksi kirjain ja numero välillä 1..99 eli esim A1, a1, mutta ei esimerkiksi 1a.
- Tee dialogi, jossa on progress bar, joka etenee ajastimen tahdissa. Progress barin voi käynnistää, nollata ja pysäyttää painikkeilla. Laita ajastimen jaksoajaksi 0,5 sekuntia. Näytä arvo myös "lcd"-näytöllä.
- Tee graafisella editorilla dialogi, johon sijoitat kuusi haluamaasi widgettiä ja erottele rinnakkaiset widgetit spacerilla toisistaan. Ryhmittele widgetit kolmeen allekkaiseen ryhmään kolmella horisonttaalisella layoutilla.
- Jatka edellistä tehtävää siten, että teet groupboxin rinnakkaisten widgettien ympärille ja ylimmän ryhmän napilla kätket alemmat widget-ryhmät.
- Tee edellisen tehtävän dialogi ohjelmallisesti. kts ohjeita
- Tee dialogi esimerkki, jossa pino on aliluokkana. Tee nappula "Laita pinoon" ja "Ota pinosta".
- Tee mallin 1. tilakone switch-case rakenteella mukainen tilakone ja lisää siihen kaksi askelta. Keksi jokin tapa näyttää askeleet.
- Tee tehtävä 23 QStack template luokkaa käyttäen.
- Tee dialogi, jolla voit laittaa ja katsella lukuja vektorissa, käytä QVector objektia.
- Tee dialogi, jolla voit laittaa ja katsella lukuja vektorissa, käytä QList objektia.
...