Olio-ohjelmointi

Näissä tehtävässä tutkitaan Qt-sovelluksen rakenteita.

Lue sivun https://peatutor.com/qt/ materiaalista, mikä on luokan QObject tarkoitus, ja mihin tarvitaan makroa Q_OBJECT.

Harjoitus6a (Qt-konsolisovellus)

HUOM!: Luo kullekin luokalle erillinen h-tiedosto ja cpp-tiedosto.

Tehtävässa luodaan Qt-konsolisovellus ja se voitaisiin luoda valitsemalla tyypiksi Qt-console application. Tee se kuitenkin ohjeiden mukaan "plain C++" tyyppisenä.

  1. Luo uusi sovellus, jonka tyyppi on Non-Qt/Plain C++
  2. Muokkaa .pro-tiedostoa:
    • Lisää rivi QT = core
    • Poista rivi CONFIG -= qt
  3. Lisää luokka MyClass
  4. Muokkaa myclass.h muotoon:
    #ifndef MYCLASS_H
    #define MYCLASS_H
    
    #include <QObject>
    #include <iostream>
    #include <QDebug>
    using namespace  std;
    
    class MyClass : public QObject {
        Q_OBJECT
    
    public:
        MyClass(QObject* parent = nullptr);
    
        void raiseMySignal();
    
    signals:
        void mySignal();
    
    public slots:
        void mySlot();
    };
    
    #endif // MYCLASS_H
    
    
  5. Muokkaa myclass.cpp muotoon:
    #include "myclass.h"
    
    MyClass::MyClass(QObject *parent) : QObject(parent) {
        connect(this, SIGNAL(mySignal()), this, SLOT(mySlot()));
    }
    
    void MyClass::raiseMySignal()
    {
        emit mySignal();
    }
    
    void MyClass::mySlot()
    {
        qDebug()<<"mySlot:ia kutsuttiin";
    }
    
    
  6. Luo main.cpp olio luokasta MyClass ja kutsu sen metodia raiseMySignal

Huomioita sovelluksesta

Edellä haluttiin käyttää luokassa MyClass Qt:n signal/slot mekanismia, joten

  • MyClass luokan tulee periä luokka QObject
  • MyClass luokassa tulee suorittaa Q_OBJECT makro
  • MyClass luokan konstruktori MyClass(QObject* parent = nullptr), mahdollistaa sen, että luokan oliolle voidaan asettaa ns. parent olio(*)
  • lauseella emit mySignal(); "nostetaan" mySignal, niminen signaali
  • lauseella
    connect(this, SIGNAL(mySignal()), this, SLOT(mySlot()));
    mySignal kytketään slottiin mySLOT

Konsolisovelluksessa qDebug toimii kuten cout. Graafisissa sovelluksissa qDebuggia voidaan käyttää tulostamaan tekstiä Qt-Creatorin Output ikkunaan. Näitä sanomia ei siis näytetä loppukäyttäjille.

Tällaisessa tehtävässä signal/slotin käyttö on turhaa. Mutta tilanteessa, jossa metodi raiseMySignal tekisi jotain tehtävää, jonka valmistumista ei voida ennakoida käyttö olisi perusteltua. Eli kun raiseMySignal saisi työnsä valmiiksi, se emitoisi tuon signaalin.

Qt-frameworkin signal-slot systeemi korvaa peristeisten callback funktioiden tarpeen.

(*) Qt-frameworkin oliomallin parent-ominaisuus tarjoaa tehokkaan ja helpon tavan hallita olioiden elinkaarta. Jokainen QObject-pohjainen olio voi saada toisen QObject-olion parentiksi. Systeemi toimii niin, että kun parent olio tuhotaan, myös sen lapsi oliot tuhotaan automaattisesti.

Callback-funktiot

Callback-funktiot ovat ohjelmoinnissa funktioita, jotka annetaan parametreina toisille funktioille. Ne suoritetaan myöhemmin, yleensä tietyn tapahtuman tai operaation valmistuttua. Callback-funktioiden avulla voidaan toteuttaa asynkronisia toimintoja, kuten tiedon hakemista palvelimelta tai käyttäjän syötteiden käsittelyä.

Makro

Makro C++-ohjelmoinnissa on esikäsittelijäohje, joka määritellään käyttämällä #define-lausetta. Makrot korvataan koodissa ennen varsinaista kääntämistä. Niitä käytetään esimerkiksi vakioiden, funktiokoodin tai koodimallien lyhentämiseen.

Q_OBJECT-makro itsessään ei sisällä suoritettavia toimenpiteitä, vaan se toimii osana Qt:n esikäsittelyä. Se ainoastaan kertoo Qt:n työkaluille, että tämä luokka sisältää Qt:n erikoisominaisuuksia ja että sille tulee luoda lisäkoodia.



Toggle Menu