Oprogramowanie i wykorzystanie stacji roboczych Wykład 4

Transkrypt

Oprogramowanie i wykorzystanie stacji roboczych Wykład 4
Mechanizm sygnałów i slotów
Mechanizm sygnałów i slotów umożliwia komunikacje˛ pomiedzy
˛
obiektami.
Oprogramowanie i wykorzystanie
stacji roboczych
Sygnał jest komunikatem informujacym,
˛
o wystapieniu
˛
pewnego
zdarzenia. Obiekty z biblioteki Qt emituja˛ ((emit)) sygnał w
momencie wystapienia
˛
zdarzenia, np. gdy użytkownik nacisnał˛
przycisk (QPushButton) - przycisk emituje sygnał clicked.
Wykład 4
Slot jest specyficzna˛ metoda˛ obiektu z biblioteki Qt, które może
obsługiwać zdarzenie, np. zamykajaca
˛ aplikacje Qt (quit z klasy
Dr inż. Tomasz Olas
[email protected]
QApplication).
Zarówno sygnały, jak i sloty moga˛ posiadać parametry, poprzez które
można przekazywać dodatkowe informacje o zaistniałym zdarzeniu.
Instytut Informatyki Teoretycznej i Stosowanej
Politechnika Cz˛estochowska
Sygnały można dowolnie łaczyć
˛
ze slotami (o ile posiadaja˛ takie
same parametry).
Wykład 4
Wykład 4 – p. 1/30
Sygnały i sloty - przykład użycia
Sygnały i sloty - definicja klasy
definicja klasy zawierajacej
˛ sygnały i sloty powinna znajdować sie˛ w
osobnym pliku nagłówkowym (np. myclass.h)
class MyClass: public QObject
{
Q_OBJECT
public:
MyClass();
protected slots:
void MySlot();
void MySlot2(int value);
signals:
void MySignal();
void MySignal2(int value);
};
Wykład 4 – p. 3/30
Wykład 4
Sygnały i sloty - deklaracja metod
Sygnały i sloty - łaczenie,
˛
rozłaczanie
˛
Sloty sa˛ zwykłymi metodami (poza faktem, że moga˛ być połaczone
˛
z
sygnałami) i należy je zdefiniować tak jak zwykłe metody:
Do połaczenia
˛
sygnału ze slotem służy statyczna metoda connect z
klasy QObject:
void MyClass::MySlot() {
...
}
bool QObject::connect(const QObject* sender, const char* signal,
const QObject* receiver, const char* member)
Do określenia sygnałów i slotów należy wykorzystać makra
SIGNAL() i SLOT(). Przykład:
Sygnały należy jedynie zadeklarować i nie wolno ich definiować
(odpowiedni kod zostanie wygenerowany przez narz˛edzie MOC).
MyClass a;
MyClass b;
QObject::connect(&a, SIGNAL(MySignal()), &b, SLOT(MySlot()));
QObject::connect(&a, SIGNAL(MySignal2(int)), &b, SLOT(MySlot(int)));
Do zgłoszenia (wyemitowania) wystapienia
˛
określonego zdarzenia
modelowanego przez sygnał służy konstrukcja emit
nazwa_sygnału(parametry):
Do rozłaczania
˛
połacze
˛ ń sygnałów ze slotami służa˛ metody
disconnect z klasy QObject:
emit MySignal();
...
int a = 10;
emit MySignal2(a);
bool disconnect(const char * signal=0, const QObject* receiver=0, const char * member=0);
bool disconnect(const QObject* receiver, const char * member=0);
Wykład 4 – p. 5/30
Wykład 4
Sygnały i sloty - kompilacja
Makefile i moc
Pliki zawierajace
˛ definicje klas zawierajacych
˛
sygnały i sloty należy
przetworzyć narz˛edziem MOC:
OBJS = main.o mywidget.o mywidget.moc.o
all: program
moc myclass.h -o myclass_moc.cpp
Zostanie w ten sposób wygenerowany dodatkowy plik źródłowy, który
należy zlinkować z pozostałymi plikami źródłowymi projektu. Np.:
%.o: %.cpp
g++ $(CXXFLAGS) -c $<
g++ -o myprogram myclass.cpp myclass_moc.cpp -lqt-mt
%.moc.cpp: %.cpp
moc -o $@ $*.h
program: $(OBJS)
g++ -o program $(OBJS) -lqt-mt
clean:
rm *.o
rm *.moc.o
rm *.moc.cpp
Wykład 4 – p. 7/30
Wykład 4
QTimer - przykład
Klasa QTimer
Klasa QTimer służy do generowania zdarzenia QTimerEvent w
stałych odstepach
˛
czasu.
Tworzac
˛ obiekt klasy QTimer określamy do którego obiektu bed
˛ a˛
takie zdarzenia kierowane:
QTimer(QObject * parent=0)
Użyteczne metody:
int start(int msec, bool singleShot = FALSE)
...
QTimer *timer = new QTimer(myObject);
connect(timer, SIGNAL(timeout()), myObject, SLOT(timerDone()));
timer->start(10000, TRUE);
QTimer *t = new QTimer( myObject);
connect(t, SIGNAL(timeout()), SLOT(processOneThing()));
t->start(1000);
...
void stop()
void changeInterval(int msec)
Obsługa zdarzenia może zostać zrealizowana przy wykorzystaniu
metody QObject::timerEvent(QTimerEvent *), lub poprzez sygnał
timeout().
Z jednym obiektem może być zwiazanych
˛
dowolna liczba sygnałów.
Wykład 4
Wykład 4 – p. 9/30
Rysowanie
Rysowanie - typowe wykorzystanie
Do rysowania służy klasa QPainter.
Typowe zastosowanie:
Służy ona do rysowania w obszarach obiektów klas dziedziczacych
˛
po klasie QPaintDevice (widgety, ale również obiekty klas
QPixmap, QPicture i QPrinter).
Utworzyć obiekt klasy QPainter
Do rysowania służy zestaw niskopoziomowych metod klasy
QPainter umożliwiajacych
˛
rysowanie linii, elips, prostokatów,
˛
wpisywanie tekstu, wklejanie rysunków, itp.
Usunać
˛ obiekt klasy QPainter
Ustawić pedzel,
˛
sposób wypełnienia, czcionk˛e, itp.
Wywołać metody do rysowania
W wiekszości
˛
przypadków rysowanie odbywa sie˛ przy obsłudze
zdarzenie paintEvent:
Standardowo do rysowania wykorzystywany jest „normalny” układ
współrz˛ednych, ale może on zostać zmodyfikowany przy
wykorzystaniu zbioru transformacji.
void MyWidget::paintEvent(QPaintEvent* e)
{
QPainter paint(this);
paint.setPen(Qt::blue);
paint.drawText(rect(), AlignCenter, "The Text");
}
Przy wywyołaniu konstruktora określa sie˛ obiekt na którym bed
˛ a˛
dokonywane operacje rysowania.
Wykład 4 – p. 11/30
Wykład 4
QPainter - współrzedne
˛
QPainter - ustawienia
void MyWidget::paintEvent( QPaintEvent * )
{
QPainter p( this );
p.setPen( darkGray );
p.drawRect( 1,2, 5,4 );
p.setPen( lightGray );
p.drawLine( 9,2, 7,7 );
}
Czcionka - setFont(const QFont &font), font(), fontInfo(),
P˛edzel - setBrush(BrushStyle style), brush(),
Pióro - setPen(const QPen &pen), pen(),
Tło (Opaque lub Transparent) setBackgroundMode(BGMode m),
backgroundMode(),
Kolor tła - setBackgroundColor(const QColor &c),
backgroundColor(),
Pozycja wirtualnego kursora (metoda LineTo - moveTo(int x, int y),
pos(),
Transformacje układu współrz˛ednych,
Obcinanie - setClipping(bool enable), setClipRegion(const QRegion
&rgn, CoordinateMode m = CoordDevice).
Wykład 4 – p. 13/30
Transformacje układu wpółrzednych
˛
I
Wykład 4
Macierz transformacji I
W klasie QPainter zaimplementowano mechanizm transformacji 2D
układu wpółrz˛ednych. Jest on analogiczny do modelu opisanego w
ksiażce
˛
Foley & Van Dam i stosowanego w standardzie OpenGL.
Przy określaniu transformacji wykorzystywana jest tzw. macierz
transformacji ((transformation matrix)). Jest ona wykorzystywana do
ustawienia położenia obiektów w modelu.
Składa sie˛ on z trzech etapów:
Do modyfikacji macierzy transformacji służa˛ metody:
określenie transformacji ((transformations)) układu
współrz˛ednych modelu,
void QPainter::rotate(double a),
ustalenie okna ((window)), poprzez które określamy granice
widoku we współrz˛ednych modelu,
void QPainter::translate(double dx, double dy),
określenie widoku ((viewport)) we współrz˛ednych urzadzenia
˛
graficznego (projekcja modelu na urzadzeniu).
˛
void QPainter::resetMatrix().
void QPainter::scale(double sx, double sy),
void QPainter::shear(double sh, double sv),
Nie wszystkie wyżej wymienione etapy musza˛ zawsze wystepować.
˛
Wykład 4 – p. 15/30
Wykład 4
Transformacje - przykład 1
Macierz transformacji II
Klasa QMatrix określa dwuwymiarowe transformacje układu
współrz˛ednych.
void Transformation::paintEvent(QPaintEvent* e)
{
QPainter p(this);
Wykorzystywana jest w tym celu macierz o rozmiarze 3 × 3:
p.setPen(Qt::red);
p.drawLine(0, 0, 50, 50);
p.setPen(Qt::darkRed);
p.drawText(0, 0, 60, 20, Qt::AlignHCenter | Qt::AlignVCenter, "(0,0)");
p.drawText(50, 50, 60, 20, Qt::AlignHCenter | Qt::AlignVCenter, "(50,50)");
p.translate(0, height());
p.rotate(270);
p.setPen(Qt::blue);
p.drawLine(0, 0, 50, 50);
p.setPen(Qt::darkBlue);
p.drawText(0, 0, 60, 20, Qt::AlignHCenter | Qt::AlignVCenter, "(0,0)");
p.drawText(50, 50, 60, 20, Qt::AlignHCenter | Qt::AlignVCenter, "(50,50)");


m11 m12 0


 m21 m22 0 
dx
dy 1
Macierz transformacji przekształca punkt na płaszczyźnie na punkt o
innych współrz˛ednych:
x′ = m11 · x + m21 · y + dx
,
y′ = m22 · y + m12 · x + dy
gdzie (x, y) sa˛ współrz˛ednymi oryginalnego punktu, natomiast
współrz˛edne (x′ , y′ ) określaja˛ punkt po transformacji.
}
Wykład 4 – p. 17/30
Macierz transformacji III
Wykład 4
Macierz transformacji - przykład
QMatrix m;
m.translate(10, -20);
m.rotate(25);
m.scale(1.2, 0.7);


m11 m12 0


 m21 m22 0 
dx
dy 1
elementy dx i dy macierzy transformacji określaja˛ odpowiednio
poziome i pionowe przesuniecie
˛
układu współrz˛ednych,
elementy m11 i m22 odpowiadaja˛ za skalowanie po odpowiednio po
osi x i y,
elementy m12 i m21 określaja˛ poziome i pionowe ścinanie.
W klasie QMatrix można bezpośrednio ustawić te wartości:
QMatrix(double m11, double m12, double m21, double m22, double dx, double dy),
setMatrix(double m11, double m12, double m21, double m22, double dx, double dy).
Wykład 4 – p. 19/30
double a
= pi/180 * 25;
double sina = sin(a);
double cosa = cos(a);
QMatrix m1(1, 0, 0, 1, 10, -20);
QMatrix m2(cosa, sina,
-sina, cosa, 0, 0);
QMatrix m3(1.2, 0, 0, 0.7, 0, 0);
QMatrix m;
m = m3 * m2 * m1;
Wykład 4
Operacje na macierzach transformacji
Ustawienie okna
Macierz jednostkowa:

Ustawiane okno określa granice modelu, którego projekcja bedzie
˛
wyświetlana na urzadzeniu
˛
graficznym.

1 0 0


 0 1 0 
0 0 1
Określajac
˛ okno wykorzystujemy współrz˛edne logiczne (modelu).
Do ustawienia okna służa˛ metody:
void QPainter::setWindow(int x, int y, int w, int h),
Do załadowania macierzy jednostkowej do aktualnej macierzy
transformacji służy metoda void QPainter::resetMatrix(),
void QPainter::setWindow(const QRect & r).
Domyślnie współrz˛edne okna sa˛ takie same jak granice urzadzenia
˛
graficznego.
Metody do operowania na stosie macierzy transformacji:
void QPainter::save(),
void QPainter::restore().
Wykład 4
Wykład 4 – p. 21/30
Transformacje - przykład 2
Ustawienie widoku
void Transformation::paintEvent(QPaintEvent* e)
{
QPainter p(this);
p.setWindow(-200, -200, 400, 400);
p.setViewport(10, 10, width() - 20, height() - 20);
p.setBrush(Qt::SolidPattern);
p.drawEllipse(-200, -200, 400, 400);
p.setFont(QFont("Helvetica", 40, QFont::Bold));
Widok określa położenie i rozmiary prezentowanego modelu na
danym urzadzeniu
˛
graficznym.
Ustalajac
˛ widok wykorzystuje sie˛ współrz˛edne urzadzenia
˛
graficznego.
Do określenia widoku wykorzystuje sie˛ metody:
void QPainter::setViewport(int x, int y, int w, int h),
void QPainter::setViewport (const QRect & r).
p.rotate(-90);
for (int i = 1; i <= 12; ++i)
{
p.rotate(30);
p.setPen(QPen(Qt::white, 3));
p.drawLine(190, 0, 200, 0);
p.setPen(QPen(Qt::yellow, 3));
QString number;
number.setNum(i);
p.drawText(150, -20, 40, 40, Qt::AlignHCenter | Qt::AlignVCenter, number);
}
Domyślne współrz˛edne widoku sa˛ identyczne z współrz˛ednymi
urzadzenia
˛
graficznego.
}
Wykład 4 – p. 23/30
Wykład 4
QInputDialog
QInputDialog - przykład
QString getText ( QWidget * parent, const QString & title, const QString & label,
QLineEdit::EchoMode mode = QLineEdit::Normal, const QString & text = QString(), bool * ok =
0, Qt::WindowFlags f = 0 ),
int getInteger ( QWidget * parent, const QString & title, const QString & label, int value = 0, int
#include <qapplication.h>
#include <qinputdialog.h>
#include <unistd.h>
minValue = -2147483647, int maxValue = 2147483647, int step = 1, bool * ok = 0,
Qt::WindowFlags f = 0 ),
double getDouble ( QWidget * parent, const QString & title, const QString & label, double value
= 0, double minValue = -2147483647, double maxValue = 2147483647, int decimals = 1, bool *
int main(int argc, char** argv)
{
QApplication app(argc, argv);
ok = 0, Qt::WindowFlags f = 0 ),
bool ok;
QString application =
QInputDialog::getText(NULL, "Run", "Nazwa programu:", QLineEdit::Normal,
QString::null, &ok, 0 );
if (ok == true)
{
execlp(application, application, NULL);
}
QString getItem ( QWidget * parent, const QString & title, const QString & label, const
QStringList & list, int current = 0, bool editable = true, bool * ok = 0, Qt::WindowFlags f = 0 ).
}
Wykład 4 – p. 25/30
QColorDialog
Wykład 4
QFontDialog
QColor QColorDialog::getColor ( const QColor & initial = Qt::white, QWidget * parent = 0 ),
QFont getFont ( bool * ok, QWidget * parent = 0 ),
QRgb QColorDialog::getRgba ( QRgb initial, bool * ok = 0, QWidget * parent = 0 ).
QFont getFont ( bool * ok, const QFont & initial, QWidget * parent, const QString & caption ).
Wykład 4 – p. 27/30
Wykład 4
QMessageBox
QFileDialog
StandardButton information ( QWidget * parent, const QString & title, const QString & text,
QString getOpenFileName ( QWidget * parent = 0, const QString & caption = QString(), const
StandardButtons buttons = Ok, StandardButton defaultButton = NoButton ),
QString & dir = QString(), const QString & filter = QString(), QString * selectedFilter = 0,
StandardButton critical ( QWidget * parent, const QString & title, const QString & text,
Options options = 0 ),
StandardButtons buttons = Ok, StandardButton defaultButton = NoButton ),
QString getSaveFileName ( QWidget * parent = 0, const QString & caption = QString(), const
StandardButton question ( QWidget * parent, const QString & title, const QString & text,
QString & dir = QString(), const QString & filter = QString(), QString * selectedFilter = 0,
StandardButtons buttons = Ok, StandardButton defaultButton = NoButton ),
Options options = 0 ),
StandardButton warning ( QWidget * parent, const QString & title, const QString & text,
QString getExistingDirectory ( QWidget * parent = 0, const QString & caption = QString(),
StandardButtons buttons = Ok, StandardButton defaultButton = NoButton ),
const QString & dir = QString(), Options options = ShowDirsOnly ),
void about ( QWidget * parent, const QString & title, const QString & text ),
QStringList getOpenFileNames ( QWidget * parent = 0, const QString & caption = QString(),
const QString & dir = QString(), const QString & filter = QString(), QString * selectedFilter = 0,
void aboutQt ( QWidget * parent, const QString & title = QString() ).
Options options = 0 ).
question
information
warning
critical
Wykład 4 – p. 29/30
Wykład 4

Podobne dokumenty