Programowanie C++ Qt4 w systemie Gnu-Linux/Sygnały i Sloty++
Zobacz na youtube
[edytuj]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:
- Klasa zawiera Obiekt
QStack<QString> *m_stack // m_stack jest wskaźnikiem do obiektu(kontenera) typu QStack<QString>
- Klasa zawiera dwie funkcje push() i pop() do odkładania i pobierania elementów na stos
- Klasa zawiera sygnał Wymitujemy go dy stos jest pusty, oraz z gdy stos ponownie posiada dane.
void stackEmpty(bool);
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)