Rozdział 5 Creating custom widgets Autor: Bartłomiej Suliga.

Slides:



Advertisements
Podobne prezentacje
Wstęp do strumieni danych
Advertisements

C++ wykład 2 ( ) Klasy i obiekty.
C++ wykład 4 ( ) Przeciążanie operatorów.
Język C/C++ Funkcje.
Programowanie wizualne
Deklaracje i definicje klas w C++ Składowe, pola, metody Konstruktory
Klasy i obiekty.
Wzorce.
Systemy rozproszone W. Bartkiewicz
Tworzenie i obsługa programów – przykład 3 uwagi cd. Wykorzystując różne klasy biblioteki języka Java należy pamiętać w jakim pakiecie się znajdują. Wszystkie.
MS Access 2000 Tworzenie tabel Piotr Górczyński 2005.
Prezentcja Power Pointa na temat obsługi programu Power Point
ODE Triggery. Wstęp n Triggery są trójką zdarzenie-warunek-akcja (event-condition- action). n Zdarzenia mogą być proste lub złożone, co zostanie omówione.
Obiektowe metody projektowania systemów Command Pattern.
C++ wykład 2 ( ) Klasy i obiekty.
Wstęp do Qt Qt to zestaw przenośnych bibliotek i narzędzi programistycznych dedykowanych dla języka C++ podstawowym składnikiem są klasy służące do budowy.
Seminarium Informatyka Prowadzący dr Grzegorz Wójcik
Czytanie, pisanie i rysowanie – cd.. Jeszcze jeden strumyk PrintStream działa jak PrintWriter, ale: Używa domyślnego (systemowego) kodowania Nie wyrzuca.

„Zasady formatowania plików w formacie Microsoft Word”
C# Windows Forms Zastosowania Informatyki Wykład 3
Opracowała: Iwona Kowalik
Tworzenie aplikacji mobilnych
Opracowanie Dorota Libera
Lokalizacja i Globalizacja na witrynie w Visual Web Developer 2008 (ASP.Net) Daniel Literski.
Programowanie obiektowe III rok EiT
Autorka : Gosia Okrasa Kl. 2 gim. CZĘŚĆ I - PODSTAWY
Programowanie obiektowe – zastosowanie języka Java SE
JAVA c.d.. Instrukcji wyboru SWITCH używamy, jeśli chcemy w zależności od wartości pewnego wyrażenia wykonać jeden z kilku fragmentów kodu. Jest to w.
Programowanie obiektowe III rok EiT
Andrzej Repak Nr albumu
Java – coś na temat Klas Piotr Rosik
Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21 Dariusz Wardowski.
Programowanie obiektowe Wykład 6 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/14 Dariusz Wardowski.
Urzekające kwiatki w gimpie Samouczek
Tworzenie Aplikacji Internetowych dr Wojciech M. Gańcza 8.
MICROSOFT Access TWORZENIE MAKR
Formatowanie tekstu w Microsoft Word
Visual Basic w Excelu.
Prasek Aneta, Skiba Katarzyna. Funkcje stałe const to takie funkcje, które nie mogą modyfikować stanu obiektu. Oznacza to, że funkcja stała nie może zmieniać.
Kurs języka C++ – wykład 3 ( )
Kurs języka C++ – wykład 9 ( )
Treści multimedialne - kodowanie, przetwarzanie, prezentacja Odtwarzanie treści multimedialnych Andrzej Majkowski informatyka +
Programowanie strukturalne i obiektowe C++
Wydział Elektroniki Kierunek: AiR Zaawansowane metody programowania Wykład 5.
Visual Basic w Excelu - podstawy
Kurs języka C++ – wykład 4 ( )
K URS JĘZYKA C++ – WYKŁAD 2 ( ) Klasy i obiekty.
prezentacja multimedialna
Programowanie obiektowe Wykład 9 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/15 Dariusz Wardowski.
Formatowanie dokumentów
Paweł Starzyk Obiektowe metody projektowania systemów
Wykład 4 Klasa Vec, której konstruktory alokują pamięć dla obiektów 1.Przykład definicji klasy Vec 2.Definicje konstruktorów i destruktora 3.Definicja.
Wykład 2 Klasa Zesp i jej hermetyzacja 1.Przykład definicji klasy Zesp 2.Zmiana definicji klasy 3.Zmienne i funkcje statyczne PO2-1 / 28.
Wykład 5 Klasa Vec i jej operatory 1.Kategorie operatorów 2.Operatory ogólne - przykłady 3.Operatory specjalne [ ], ( ) oraz –> 4.Operatory new i delete.
Podstawy informatyki Preprocesor Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi.
Podstawy informatyki Funkcje Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi.
K URS JĘZYKA C++ – WYKŁAD 3 ( ) Przenoszenie Składowe statyczne Funkcje wbudowane Argumenty domyślne.
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego Moduł ECDL-AM5 Bazy danych, poziom zaawansowany Tabele, relacje.
C++ mgr inż. Tomasz Turba Politechnika Opolska 2016.
Programowanie Obiektowe – Wykład 6
Kurs języka C++ – wykład 3 ( )
Klasy, pola, obiekty, metody. Modyfikatory dostępu, hermetyzacja
(według:
Delegaty Delegat to obiekt „wiedzący”, jak wywołać metodę.
Programowanie Obiektowe – Wykład 2
Programowanie obiektowe – zastosowanie języka Java SE
Wstęp - Prosta aplikacja internetowa w technologii Java EE 5
Zapis prezentacji:

Rozdział 5 Creating custom widgets Autor: Bartłomiej Suliga

Przekształcanie istniejących widgetów HexSpinBox- spin box z wartościami w notacji szesnastkowej Dziedziczymy po klasie QSpinBox Implementujemy niektóre metody

HexSpinBox.h #ifndef HEXSPINBOX_H #define HEXSPINBOX_H #include class QRegExpValidator; class HexSpinBox : public QSpinBox { Q_OBJECT //makro wymagane dla klas, w których definiowane są sloty sygnały lub właściwości. public: HexSpinBox(QWidget *parent = 0); //konstruktor protected: // trzy funkcje z QSpinBox, które musimy zaimplementwać QValidator::State validate(QString &text, int &pos) const; int valueFromText(const QString &text) const; QString textFromValue(int value) const; private: QRegExpValidator *validator; }; #endif

HexSpinBox.cpp #include //plik z definicjami wszystkich klas QtGui #include "hexspinbox.h //nasz plik nagłówkowy HexSpinBox::HexSpinBox(QWidget *parent) : QSpinBox(parent) { setRange(0, 255); //ustawiamy domyślny zakres od 0x00 do 0xFF validator = new QRegExpValidator(QRegExp("[0-9A-Fa-f]{1,8}"), this); //akceptujemy wyrażenia o długości od 1-8 znaków z zakresu 0-9, a-f,A-F } QValidator::State HexSpinBox::validate(QString &text, int &pos) const { return validator->validate(text, pos); } //funkcja sprawdza czy wprowadzony tekst jest poprawny, może zwrócić trzy różne wyniki: Invalid (tekst niepoprawny), Intermediate ( część tekstu nadaje się do przyjęcia) lub Acceptable (tekst poprawny).

HexSpinBox.cpp QString HexSpinBox::textFromValue(int value) const { return QString::number(value, 16).toUpper(); } //funkcja zamienia wartość całkowitą na string, używana kiedy zmieniamy wartość za pomocą strzałek SpinBoxa. Używa statycznej funkcji number z drugim argumentem 16, żeby przekonwertować wartość na szestanstkową int HexSpinBox::valueFromText(const QString &text) const {bool ok; return text.toInt(&ok, 16); } // konwersja odwrotna używana kiedy wpisujemy wartość ręcznie i wciśniemy enter, gdy wprowadzona wartość nie jest poprawnym wyrażeniem szesnastkowym parametr ok. przyjmie wartość false;

Tworzenie własnego widgetu. Icon Editor- prosty widget do edycji ikon Dziedziczymy po klasie QWidget Implementujemy niektóre metody i zdarzenia

IconEditor.h #ifndef ICONEDITOR_H #define ICONEDITOR_H #include class IconEditor : public QWidget { Q_OBJECT //makra do ustawiania niektórych właściwości(każde posiada swój typ oraz funkcje READ i WRITE) Q_PROPERTY(QColor penColor READ penColor WRITE setPenColor) Q_PROPERTY(QImage iconImage READ iconImage WRITE setIconImage) Q_PROPERTY(int zoomFactor READ zoomFactor WRITE setZoomFactor) public: IconEditor(QWidget *parent = 0); void setPenColor(const QColor &newColor); QColor penColor() const { return curColor; } void setZoomFactor(int newZoom);

IconEditor.h int zoomFactor() const { return zoom; } void setIconImage(const QImage &newImage); QImage iconImage() const { return image; } QSize sizeHint() const; protected: //zdarzenia klasy QWidget, które musimy implementować void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void paintEvent(QPaintEvent *event); private: void setImagePixel(const QPoint &pos, bool opaque); QRect pixelRect(int i, int j) const; //prywatne pola przechowujące właściwości QColor curColor; QImage image; int zoom; }; #endif

IconEditor.cpp #include #include "iconeditor.h" IconEditor::IconEditor(QWidget *parent) : QWidget(parent) { setAttribute(Qt::WA_StaticContents); setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); //widget może być rozszerzony, jednak nie może być zmniejszony poniżej minimum curColor = Qt::black; //ustawiamy kolor na czarny zoom = 8; // każdy pixel ikony w edytorze będzie przedstawony jako kwadrat 8x8 image = QImage(16, 16, QImage::Format_ARGB32); //Bitmapa 16 x 16 pixeli w formacie ARGB image.fill(qRgba(0, 0, 0, 0));//wypełniamy bitmapę } QSize IconEditor::sizeHint() const //funkcja zwraca idealny rozmiar widgetu { QSize size = zoom * image.size(); if (zoom >= 3) size += QSize(1, 1); //zwiększamy rozmiar o siatkę jeśli zoom jest >= 3 return size; } // bardzo ważna funkcja dla QTDesignera, przy tworzeniu layoutów

Qt::WA_StaticContents Właściwość ta powoduje, że widget jest na stałe przyczepiony do lewego górnego rogu i jego zawartość nie zmienia się podczas zmieniania jego rozmiaru. Normalnie kiedy zmieniamy rozmiar widgetu, Qt wykonuje zdarzenie Paint Event, dzięki właściwości WA_Static Contents, podczas zmniejszania PaintEvent nie jest niepotrzebnie wykonywany.

IconEditor.cpp void IconEditor::setPenColor(const QColor &newColor) //funkcja ustawiająca kolor { curColor = newColor; } void IconEditor::setIconImage(const QImage &newImage) //ustawia ikonę do edycji { if (newImage != image) { image = newImage.convertToFormat(QImage::Format_ARGB32);//zmieniamy format na ARGB32 update(); //Odświeżenie bitmapy updateGeometry(); //zmiana SizeHinta } void IconEditor::setZoomFactor(int newZoom) { if (newZoom < 1) newZoom = 1; if (newZoom != zoom) { zoom = newZoom; update(); updateGeometry(); }

PaintEvent Paint Event jest wywoływany gdy: widget jest pokazywany po raz pierwszy zmieniamy rozmiar widgetu widget był zakryty przez inne okno i następuje jego odsłonięcie Możemy także wywołać PaintEvent ręcznie używając funkcji QWidget::update() lub QWidget::re-paint().

IconEditor.cpp void IconEditor::paintEvent(QPaintEvent *event) { QPainter painter(this); if (zoom >= 3) { //rysujemy siatkę painter.setPen(palette().foreground().color()); // ustawiamy kolor z palety for (int i = 0; i <= image.width(); ++i) painter.drawLine(zoom * i, 0, zoom * i, zoom * image.height()); for (int j = 0; j <= image.height(); ++j) painter.drawLine(0, zoom * j, zoom * image.width(), zoom * j); } for (int i = 0; i < image.width(); ++i) { for (int j = 0; j < image.height(); ++j) { QRect rect = pixelRect(i, j); //zwraca, region który trzeba namalować if (!event->region().intersect(rect).isEmpty()) { QColor color = QColor::fromRgba(image.pixel(i, j)); painter.fillRect(rect, color);//malujemy powiększony pixel }

IconEditor.cpp QRect IconEditor::pixelRect(int i, int j) const { if (zoom >= 3) { return QRect(zoom * i + 1, zoom * j + 1, zoom - 1, zoom - 1); //zmniejszamy o siatkę } else { return QRect(zoom * i, zoom * j, zoom, zoom); } void IconEditor::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { setImagePixel(event->pos(), true); } else if (event->button() == Qt::RightButton) { setImagePixel(event->pos(), false); }

IconEditor.cpp void IconEditor::mouseMoveEvent(QMouseEvent *event) { if (event->buttons() & Qt::LeftButton) { setImagePixel(event->pos(), true); } else if (event->buttons() & Qt::RightButton) { setImagePixel(event->pos(), false); } void IconEditor::setImagePixel(const QPoint &pos, bool opaque) { // funkcja kolorująca lub czyszcząca dany pixel int i = pos.x() / zoom; int j = pos.y() / zoom; if (image.rect().contains(i, j)) { //sprawdzamy czy punkt znajduje się na obrazku if (opaque) { image.setPixel(i, j, penColor().rgba()); //kolorujemy } else { image.setPixel(i, j, qRgba(0, 0, 0, 0)); //czyścimy } update(pixelRect(i, j)); }

Jak zintegrować widgety z QtDesignerem? promotion approach (Przekształcanie) plugin approach

Integrujemy HexSpinBox 1.Tworzymy zwykły QSpinBox 2.Klikamy prawym przyciskiem myszy i wybieramy opcję Przekształć do.. 3.Ustawiamy odpowiedni nagłówek klasy

Integrujemy IconEditor Musimy napisać odpowiedni plugin i zintegrować go z QtDesignerem. Zakładamy,że plugin znajduje się w katalogu iconeditorplugin,a pliki źródłówe w katalogu iconeditor. Dziedziczymy po klasie QDesignerCustomWidgetInterface i implementujemy niektóre virtualne funkcje.

IconEditorPlugin.h #include class IconEditorPlugin : public QObject, public QDesignerCustomWidgetInterf { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) //makro, które mówi, że dana klasa jest pluginem public: IconEditorPlugin(QObject *parent = 0); QString name() const; QString includeFile() const; QString group() const; QIcon icon() const; QString toolTip() const; QString whatsThis() const; bool isContainer() const; QWidget *createWidget(QWidget *parent); };

IconEditorPlugin::IconEditorPlugin(QObject *parent) //konstruktor : QObject(parent) { } QString IconEditorPlugin::name() const //Funkcja zwraca nazwę widgetu { return "IconEditor"; } QString IconEditorPlugin::includeFile() const { return "iconeditor.h"; } QString IconEditorPlugin::group() const //zwraca grupę do której dany widget powinien należeć, jeżeli nie ma takiej grupy w QtDesignerze zostanie ona stworzona { return tr("Image Manipulation Widgets"); } IconEditorPlugin.cpp

QIcon IconEditorPlugin::icon() const //zwraca obrazek którym widget będzie reprezentowany w QtDesignerze { return QIcon(":/images/iconeditor.png"); } QString IconEditorPlugin::toolTip() const { return tr("An icon editor widget"); } QString IconEditorPlugin::whatsThis() const { return tr("This widget is presented in Chapter 5 of C++ GUI " "Programming with Qt 4 as an example of a custom Qt " "widget."); } IconEditorPlugin.cpp

bool IconEditorPlugin::isContainer() const { // funkcja zwraca true jeśli na widgecie, możemy umieszczać inne widgety return false; } QWidget *IconEditorPlugin::createWidget(QWidget *parent) { return new IconEditor(parent); //funkcja tworząca obiekt klasy reprezntującej widget } Q_EXPORT_PLUGIN2(iconeditorplugin, IconEditorPlugin) //makro czyniące plugin dostępnym dla QtDesignera

Plik projektu Plik projektu-. pro powinien wyglądać następująco: TEMPLATE = lib CONFIG += designer plugin release HEADERS =../iconeditor/iconeditor.h \ iconeditorplugin.h SOURCES =../iconeditor/iconeditor.cpp \ iconeditorplugin.cpp RESOURCES = iconeditorplugin.qrc DESTDIR = $(QTDIR)/plugins/designer