Programowanie C++ Qt4 w systemie Gnu-Linux/Sygnały i Sloty++

Zobacz na youtube

edytuj

materiał wideo do kursu

Specjalny Stos do przechowywania napisów

edytuj

Klasę kontenera napisów stringStack zaprezentuję jako przykład na wykorzystanie mechanizmu sygnałów i slotów z biblioteki QT.

Właściwości klasy:

  1. Klasa zawiera Obiekt
     QStack<QString> *m_stack // m_stack jest wskaźnikiem do obiektu(kontenera) typu QStack<QString>
    
  2. Klasa zawiera dwie funkcje push() i pop() do odkładania i pobierania elementów na stos
  3. Klasa zawiera sygnał
     void stackEmpty(bool);
    
    Wymitujemy go dy stos jest pusty, oraz z gdy stos ponownie posiada dane.

Plik nagłówkowy

edytuj
#ifndef STRINGSTACK_H
#define STRINGSTACK_H

#include<QObject>                       //ważne !!! aby mechanizm sygnałów i slotów działał 
#include<QStack>
#include<QString>

class StringStack : public QObject      //ważne !!! aby mechanizm sygnałów i slotów działał 
{
    Q_OBJECT                            //ważne !!! aby mechanizm sygnałów i slotów działał 

    int stackCount, stackLimit;
    QStack<QString> *m_stack;           //klasyczny kontener do przechowywania napisów

public:
    explicit StringStack(QObject *parent = 0, int lim = 10);
    ~StringStack();

    QString pop();
    void push(const QString & str);
    
signals:
    void stackEmpty(bool);              //Deklaracja sygnału 

public slots:

};

#endif // STRINGSTACK_H

Więc aby działały sygnały i sloty potrzebna jest dziedziczenie po QObject jak w zaprezentowanym pliku nagłówkowym

Implementacja

edytuj
#include "stringstack.h"

StringStack::StringStack(QObject *parent, int lim) :
    QObject(parent)
{
    stackCount=0;
    m_stack=new QStack<QString>;
    stackLimit=lim;
}
QString StringStack::pop()
{
    QString s;
    if (stackCount>0) s= m_stack->pop();                        //jeśli stos zawiera elementy to można pobrać dane
    if (!(stackCount=m_stack->size())) emit stackEmpty(true);   //jeśli stos pusty wyemituj sygnał stos pusty
    return s;
}
 void StringStack::push(const QString & str) //dodajemy napis na stos 

 {
  if (stackCount==0) emit stackEmpty(false);            //!!! Ważne gdy wskaźnik stosu jest pusty to emitujemy sygnał że stos znów się zapełni
  if (stackCount==stackLimit) m_stack->removeLast();    //limit elementów na stosie (historia zapamiętuje 10 elementów)
  m_stack->push(str);                                   //Odkładamy na stos właściwy
  stackCount=m_stack->size();                           //Uaktualnienie wskaźnika stosu             
 }

 StringStack::~StringStack()
 {
     delete m_stack;
 }

Wyjaśnię może tą linijkę kodu:

if (!(stackCount=m_stack->size())) emit stackEmpty(true);

W linijce poniżej najpierw następuje przypisanie stackCount=m_stack->size() a jeśli wynik jest zerowy (każda cyfra większa od 0 to true) emitowany jest sygnał stackEmpty(true);

Dla łatwiejszego zrozumienia fragmentu napiszmy to w alternatywnej postaci. Fragment bardziej czytelny ale robi to samo!!!

stackCount=m_stack->size();
if (stackCount==0) emit stackEmpty(true);



Użycie klasy

edytuj

Klasyczny pusty projekt aplikacji QT utworzony w QtCreator z dwoma zmianami

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include"stringstack.h"                     //nasz stos plik nagłówkowy

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private slots:
    void on_popButton_clicked();

    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
    StringStack* m_stack;                     //deklarujemy wskaźnik na stos
};

#endif // MAINWINDOW_H

implementacja

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_stack = new StringStack;

    //Sterujemy przyciskiem w zależności od zapełnienia stosu
    connect(m_stack, SIGNAL(stackEmpty(bool)),ui->popButton, SLOT(setDisabled(bool)));
}

MainWindow::~MainWindow()
{
    delete ui;
    delete m_stack;
}

void MainWindow::on_popButton_clicked() //Obsługa przycisku pop
{
    ui->label->setText(m_stack->pop()); //pobieramy ze stosu
}

void MainWindow::on_pushButton_clicked() //Obsługa przycisku push
{
    m_stack->push(ui->lineEdit->text()); //dajemy napis na stos
}

Za pomocą mechanizmu sygnałów i slotów, w wyżej zaprezentowanym programie załatwiamy sobie włączanie przycisku gdy stos ma dane i wytłaczanie przycisku gdy stos pusty a wszystko za pomocą tego polecenia

connect(m_stack, SIGNAL(stackEmpty(bool)),ui->popButton, SLOT(setDisabled(bool)));


Do pobrania

edytuj

źródła klasy stringStack i prosty programik testujący !!!

http://chomikuj.pl/mysiadziura/www.marekk.dreamhosters.com/stacktest.tar,4791302197.gz(archive)