Archiwa tagu: Daj Się Poznać 2017

Posty na konkurs Daj się poznać 2017

QT Creator – dodanie niestandardowego widgetu w edytorze interfejsu graficznego

Dodanie customowego widgetu. Z menu po lewej stronie edytora interfejsu przeciągamy obiekt „Widget” w docelowe miejsce. Klikamy prawym przyciskiem myszy na widget → „Promote to …”. W oknie Promoted Widgets wpisujemy do „Promoted class name” nazwę naszej klasy, np. DrawingAreaView, natomiast w polu „Header file” ścieżkę pliku nagłówkowego, np. widgets/DrawingAreaView.h. Klikamy Add, zaznaczamy nowo dodany wpis i klikamy Promote. Nasz widget został dodany w miejsce zwykłego QWidgetu.

Pierwsze widgety, obsługa kliknięć i rysowanie

widgety w central widgecie.png

Dodałem widoki planszy. Struktura wewnętrzna widgetów zaczerpnięta jest z przykładowego projektu o nazwie „scribble” znajdującego się katalogu QT. Na ekranie mojej aplikacji znajdują się trzy widoki (widgety). Jeden (DrawingAreaView) jest główną planszą, na której zaczernia się poszczególne pola, natomiast dwa pozostałe są polami pomocniczymi zawierającymi liczby opisujące długości poszczególnych bloków. Wszystkie trzy rozmieszczone są w centralWidget’cie. Dla widgetu rowsDescription ustawiłem Layout Alignment → Right, a dla columnsDescription Layout Alignment → Bottom. Widget DrawingAreaView obsługuje kliknięcia myszy i rysuje prostokąty w różnych kolorach w zależności od klikniętego przycisku myszy.

Link do opisywanego commitu: https://github.com/ololuki/nonograms/commit/de5430e0d860d54893f93cc4b7b97d82960e2a8e

Git Gui i SSH – konfiguracja

Aby ciągle nie wpisywać hasła do githuba w Git Gui, postanowiłem w końcu skonfigurować połączenie przez SSH. W oknie Git Gui klikamy Help → Show SSH Key → Generate Key. Klucz z textBoxa kopiujemy i przechodzimy na github.com → Settings → SSH and GPG keys → New SSH key, podajemy dowolną nazwę, np. „Git Gui” i wklejamy klucz w polu Key. Wracamy do Git Gui i klikamy Remote → Add. W polu Name podajemy nazwę, np. „nonogramsSSH”, natomiast w polu Location:

git@github.com:USERNAME/REPOSITORY.git

w moim przypadku:

git@github.com:ololuki/nonograms.git

Zaznaczamy Do Nothing Else Now i klikamy Add. Przy kolejnym Pushu wystarczy wybrać Remote:nonogramsSSH i można wysyłać kolejne wersje na GitHuba bez konieczności podawania loginu i hasła.

Layout dla każdego (QWidgetu) czyli co zrobić, gdy kontrolki wewnątrz layoutu nie skalują się wraz z oknem

Dziś trochę o layoutach i definiowaniu interfejsu graficznego. Po dodaniu kilku kontrolek do layoutu zauważyłem, że podczas skalowania okna znajdujące się w jego wnętrzu kontrolki nie zmieniają swojego rozmiaru i kształtu. Efekt, który chciałem osiągnąć to skalowanie kontrolek wewnątrz okna wraz ze zmianą rozmiaru okna. Chwila w kwakania w Duck Duck Go zaprowadziła mnie do rozwiązania problemu. Mianowicie każde okno (QMainWindow) i każdy obszar typu QScrollArea powinien mieć ustawiony layout. W edytorze interfejsu po prawej stronie mamy okno z drzewem widżetów. Dla nowo stworzonego projektu zaraz pod elementem MainWindow znajduje się centralWidget. Jest to serce całego interfejsu, najważniejszy widget w oknie. Po jego lewej stronie znajduje się ikonka layoutu z czerwonym znacznikiem informującym, że layout nie został ustawiony. Aby ustawić layout wystarczy kliknąć prawym przyciskiem myszy na MainWindow → Lay Out → Lay Out Horizontaly (bądź inny wybrany przez nas layout). Można też tego dokonać klikając na MainWindow a następnie ikonkę Lay Out Horizontaly na pasku ponad oknem edycji GUI albo używając skrótu klawiszowego CTRL + H.

Po ustawieniu layoutu zawartość okna powinna zmieniać rozmiar razem z nim:

Simple Drawing Application – prosta aplikacja QT5 znaleziona w Internecie

Znalazłem w Internecie całkiem schludnie napisaną a jednocześnie w miarę prostą aplikację w QT 5 z użyciem widgetów. Aplikacja ta korzysta z frameworka testów jednostkowych Catch. Autor inspirował się książką Roberta C. Martina – Agile Software Development, Principles, Patterns, and Practices. Osobiście czytałem inną książkę Roberta C. Martina – Czysty kod, którą przy okazji mogę polecić gdyż w prosty sposób przedstawia jak pisać czytelny i łatwy do zrozumienia kod.
Link do aplikacji na GitHubie:
https://github.com/bruceoutdoors/DrawingApp

Migracja na nowy serwer i nowa domena.

31 marca otrzymałem wiadomość, że darmowy serwer hostingowy elektroda.eu kończy swoją działalność. Domena została wyłączona praktycznie z dnia na dzień. Zmusiło mnie to do poszukiwań nowego hostingu i domeny. Postanowiłem wykupić domenę, aby uniezależnić się od humorów darmowych dostawców. Sytuacja ta ma także swoje zalety, gdyż dzięki temu dowiedziałem się jak skonfigurować ustawienia DNS, jak podpiąć domenę pod hosting (w panelu rejestratora domeny edycja wpisu typu A z adresem IP serwera hostingowego) oraz że na współdzielone konto hostingowe można dostać się poprzez adres: ip serwera/~nazwa_użytkownika.

Testy jednostkowe w Qt Creatorze

W tym poście zostanie przedstawiona struktura projektu zawierającego aplikację oraz testy jednostkowe. Przedstawię dwa przykłady. Pierwszy z nich będzie oparty o wbudowaną bibliotekę QtTest, natomiast w drugim przykładzie zostanie wykorzystana biblioteka Catch, która jest lekka i składa się tylko z jednego pliku nagłówkowego.

Struktura projektu

TemplateProj struktura.png

Projekt (TemplateProj) składa się z dwóch podprojektów: standardowego projektu aplikacji (app) oraz projektu zawierającego testy jednostkowe (tests). Główny projekt (TemplateProj) to tak naprawdę tylko kontener na pozostałe projekty. Korzysta z szablonu TEMPLATE = subdirs i definiuje jedynie nazwy podkatalogów projektu. CONFIG += ordered informuje kompilator, że wymienione podkatalogi powinny być przetwarzane w takiej kolejności w jakiej są wymienione. Zapewnia to poprawną kompilację, ponieważ projekt tests korzysta z elementów projektu app. Zawartość pliku TemplateProj:

TEMPLATE = subdirs

CONFIG += ordered

SUBDIRS = \
    app \
    tests

Projekt app jest generalnie standardowym projektem aplikacji, takim jaki można stworzyć w Qt Creatorze z szablonu nowy projekt. Wpis CONFIG += console umożliwia prawidłowe działanie programu, gdy odpalamy program w terminalu zamiast domyślnego okna application output. Brak tego wpisu powoduje, że po odpaleniu aplikacji okno konsoli jest puste i wyświetla tylko standardowe „Press Return to close this window”. Zmiana opcji „Run in terminal” jest dostępna w karcie Projects → Run Settings osobno dla każdej aplikacji. DESTDIR = $$PWD/../build ustawia katalog z plikami wynikowymi na build w katalogu głównym projektu. Można tę linię pominąć, wtedy pliki wynikowe pojawią się w domyślnych katalogach debug / release.

QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += console

TARGET = TemplateProj
TEMPLATE = app

DESTDIR = $$PWD/../build

HEADERS += \
    Calculator.h

SOURCES += \
    main.cpp \
    Calculator.cpp

W głównym projekcie app dodajmy plik main.cpp oraz przykładową klasę Calculator:

#include 
#include 

int main(int argc, char *argv[])
{
	std::cout << "Example test project" << std::endl;
	Calculator calc;
	std::cout << "2 + 6 = " << calc.add(2,6) << std::endl;
	
	return 0;
}
#ifndef CALCULATOR_H
#define CALCULATOR_H

class Calculator
{
public:
	int add(int a, int b);
};

#endif // CALCULATOR_H
#include "Calculator.h"

int Calculator::add(int a, int b)
{
	return a + b;
}

Do tego miejsca wszystkie elementy są niezależne od użytej technologii testów. Natomiast projekt z testami jest już dostosowywany do danej biblioteki testowej.

QtTest

QtTest to biblioteka dostarczana wraz z całym pakietem Qt, więc stworzenie projektu zawierającego testy jednostkowe jest możliwe bez wprowadzania dodatkowych zależności od zewnętrznych bibliotek.
Najprostszy plik projektu tests dla QtTest wygląda następująco:

QT += testlib

TARGET = TemplateProjUnitTests

SOURCES += TestMain.cpp \
    ../app/Calculator.cpp
    
INCLUDEPATH += \
    ../app

Plik TestMain.cpp (omówienie):

#include 
#include "Calculator.h"

class TestMain: public QObject
{
	Q_OBJECT
private slots:
	void adder();
};

void TestMain::adder()
{
	Calculator c;
	QCOMPARE(c.add(3,5), 8);
	QCOMPARE(c.add(3,10), 13);
}

QTEST_MAIN(TestMain)
#include "TestMain.moc"

Link do kompletnego projektu: Qt-simple-examples/ProjectStructureQTest

Catch

Catch to biblioteka testów dla C++. Jej zaletami są liberalna licencja, brak zależności od innych bibliotek oraz dystrybucja w postaci jednego pliku nagłówkowego.
Najprostszy plik projektu tests dla Catch wygląda następująco (chociaż działa także bez linijki TEMPLATE = app, ale została ona pozostawiona dla formalności):

QT += core

TARGET = TemplateProjUnitTests
TEMPLATE = app

CONFIG += console

SOURCES += TestMain.cpp \
    CalculatorTest.cpp \
    ../app/Calculator.cpp

INCLUDEPATH += \
    ../app \
    ../lib

Plik TestMain.cpp - odpowiada za prawidłowe wywołanie pozostałych plików źródłowych z testami. Zawiera w sobie definicje jednego makra i include biblioteki Catch. Makro CATCH_CONFIG_MAIN powinno zostać wywołane tylko w jednym miejscu projektu.

#define CATCH_CONFIG_MAIN
#include "catch.hpp"

Właściwy plik z testami:

#include "catch.hpp"
#include "Calculator.h"

TEST_CASE("add test") {
	Calculator c;

	REQUIRE(c.add(3,5) == 8);
	REQUIRE(c.add(3,10) == 13);
}

Link do kompletnego projektu: Qt-simple-examples/ProjectStructureCatch
O strukturze projektu: link
Przykład aplikacji wykorzystującej bibliotekę Catch: link

Potencjalne problemy

  • qmake exited with code 2 - prawdopodobnie ścieżka projektu jest zbyt długa - wystarczy przenieść projekt do katalogu o krótszej ścieżce
  • inne błędy przy kompilacji - kliknąć prawym przyciskiem na projekcie → Run qmake a następnie Rebuild

Stworzenie projektu, commit i push na githuba

Nadszedł czas aby skupić się na kodzie programu i zapełnić święcące dotychczas pustkami repozytorium projektu: Obrazki logiczne. Poniżej przedstawiam krok po kroku tworzenie nowego projektu w Qt Creatorze i umieszczanie go na githubie.

Krok po kroku

W Qt Creatorze stworzyłem nowy projekt jako Qt Widgets Application i od razu dodałem do gita. W karcie „projects” odznaczyłem „Shadow build” dla wszystkich konfiguracji po to aby mieć wszystkie pliki wynikowe w podkatalogach debug i release w głównym katalogu projektu. Do akcji związanych z gitem używam Git Gui (Qt Creator → Tools → Git → Git Tools → Git Gui). Przy pierwszym uruchomieniu Git Gui trzeba go skonfigurować. Wchodzimy w Edit → Options… i podajemy User Name oraz Email Address – nazwa użytkownika i e-mail konta na githubie. Ustawiamy kodowanie znaków na UTF-8, resztę można pozostawić bez zmian. Klikamy Save i wracamy do ekranu głównego. Jeśli w oknie Unstaged changes pojawiły się jakieś pliki, których nie chcemy zamieszczać w repozytorium (np. pliki generowane przez IDE lub kompilator) to musimy stworzyć plik .gitignore w głównym katalogu projektu. W pliku .gitignore będą znajdowały się wyrażenia regularne określające pliki wykluczone z repozytorium. Zawartość pliku .gitignore dla projektu stworzonego w Qt:

/debug
/release
*.user
*.stash
Makefile
Makefile.Debug
Makefile.Release
ui_*.h

Po stworzeniu i uzupełnieniu pliku .gitignore wracamy do Git Gui. Po kliknięciu Rescan niechciane pliki powinny zniknąć. Teraz w oknie Unstaged changes powinny znajdować się jedynie pliki źródłowe i główny plik projektu. Kliknięcie Stage Changed przenosi pliki do okna Staged Changes, które zawiera wszystkie pliki, które zostaną dodane do przyszłego commitu. Wypełniamy opis zmian i klikamy commit, który dodaje pliki do lokalnego repozytorium. Zaznaczenie opcji Ammend Last Commit pozwala na modyfikację ostatniego commitu – dzięki temu można uniknąć niepotrzebnego rozrostu listy edycji, w sytuacji gdy zapomnieliśmy dodać jakiegoś pliku lub źle opisaliśmy poprzedni commit. Jednak warto być tutaj ostrożnym gdyż komenda ammend zastępuje całkowicie poprzedni commit bez śladu w historii zmian. Powinno się unikać komendy Ammend w publicznych repozytoriach.

Przed pierwszym wysłaniem kodu do githuba trzeba skonfigurować zdalne repozytorium. W Git Gui klikamy Remote → Add. W polu Name wpisujemy nazwę repozytorium np. „nonograms”, a w polu Location adres repozytorium „https://github.com/ololuki/nonograms”. Po kliknięciu Add możemy wykonać pierwszy „Push”. Po kliknięciu przycisku Push w oknie Push, trzeba będzie podać nazwę użytkownika i hasło z githuba. Jeśli wszystko poszło jak trzeba nasz kod pojawi się na githubie.

Możliwe problemy

Jeśli używamy oprogramowania SPICE to mogą pojawić się problemy z lokalizacją plików ustawień gita. Domyślnie znajdują się one w katalogu domowym użytkownika ~/ czyli w Windowsie w C:\Users\username\ natomiast SPICE (orCAD) wprowadza zmienną środowiskową HOME z dziwną ścieżką, na przykład C:\Users\LUK\AppData\Roaming\SPB_16.6 więc po zainstalowaniu orCADa pliki ustawień gita a także kilku innych programów mogą trafić do tego śmiesznego katalogu. Aby to naprawić wystarczy przenieść zawartość katalogu znajdującego się pod zmienną środowiskową HOME do naszego katalogu domowego (C:\Users\username\) a następnie usunąć zmienną środowiskową HOME z systemu. Po wszystkim konieczne jest ponowne uruchomienie komputera.

Qt Creator – konfiguracja kompilatora i debugera.

W tym poście opiszę jak rozpocząć przygodę z Qt na Windowsie. Instalacja środowiska Qt Creator i kompilatora jest dość prosta – generalnie ogranicza się do klikania Next. Zainstalowanie debugera może sprawić trochę więcej problemów jeśli robimy to pierwszy raz, dlatego właśnie powstał ten post. Głównie jako ściąga dla mnie gdybym w przyszłości musiał znowu konfigurować środowisko, ale może któryś z czytelników także z tego kiedyś skorzysta.

Qt creator

Środowisko Qt można pobrać tutaj: Qt Download Bezpośredni link do wersji użytej przeze mnie (5.8.0 VS2015 x64): qt-opensource-windows-x86-msvc2015_64-5.8.0.exe.mirrorlist

Visual Studio 2015

Visual Studio 2015 w darmowej wersji Community można ściągnąć tutaj: Visual Studio Community 2015 Update 3 lub Visual Studio Community 2015 Update 3 (bez logowania) Ewentualnie: Visual Studio Community 2015 (starsza wersja)
Podczas instalacji trzeba będzie zaznaczyć opcje „Visual C++” oraz „Universal Windows App Development Tools”.

Hello world

Po zainstalowaniu IDE i kompilatora powinno się dać skompilować pierwszy pierwszy program. Po uruchomieniu Qt Creatora mamy listę przykładowych programów. Po wybraniu dowolnego z nich pojawia się strona „Configure project”. Pojawia się ona przy pierwszym uruchomieniu danego projektu i wystarczy kliknąć przycisk „Configure project”. Następnie dobrze jest przejść do karty „Projects” i odznaczyć opcję „Shadow build” (osobno dla każdej konfiguracji debug i release). Kiedy opcja ta jest zaznaczona pliki wynikowe będą przechowywane w katalogu poza głównym katalogiem projektu. Odznaczenie tej opcji spowoduje, że wszystkie pliki generowane przez kompilator pozostaną wewnątrz głównego katalogu projektu w podfolderach build lub release. Język interfejsu Qt Creatora można zmienić w Tools → Options → Environment.

Debuging tools

Konfiguracja debugera (Setting Up Debugger). Ze strony Windows Driver Kit ściągamy „Get Debugging Tools for Windows (WinDbg) (from the SDK)” Bezpośredni link: SDKSETUP.EXE
Po odpaleniu pobranego SDKSETUP.EXE będzie możliwość zainstalowania lub pobrania Windows Software Devepment Kit. Jeśli wybraliśmy opcję pobierania do późniejszej instalacji to po ściągnięciu musimy odpalić nowo pobrany SDKSETUP.exe z folderu ustawionego jako „Download Path” (domyślnie C:\Users\Username\Downloads\Windows Kits\10\StandaloneSDK). Wybieramy komponenty do zainstalowania – najważniejsze są Debugging Tools for Windows oraz Windows Software Development Kit, ale można na wszelki wypadek zainstalować wszystko.

Debugowanie

Po pomyślnym zainstalowaniu narzędzi do debugowania możemy sprawdzić czy Qt Creator wykryje nasz debugger, a następnie spróbujemy go przetestować. Wchodzimy w Tools → Options → Build & Run → Debuggers i powinniśmy zobaczyć dostępne debugery dla architektury x86 oraz x64. Teraz możemy przetestować debuger i jeśli wszystko zostało zainstalowane prawidło to powinien działać od razu bez dodatkowej konfiguracji.

Możliwe problemy

  • Podczas instalacji Visual Studio może wyskoczyć błąd instalacji Windows SDK. Jeśli jednak pomimo tego błędu będzie możliwa kompilacja w Qt Creatorze to znaczy, że wszystkie potrzebne komponenty zostały zainstalowane prawidłowo i nie warto się tym przejmować.
  • Podczas instalacji SDK może pojawić się komunikat „The features installed on this computer are up-to-date” a pomimo to debuger nie będzie zainstalowany – wchodzimy wtedy w Panel sterowania → Programy i funkcje, znajdujemy wpis „Windows Software Development Kit – Windows 10.0.14393.33” i klikamy prawym → Zmień.

Daj się poznać 2017 – Obrazki logiczne.

Ruszyła kolejna edycja konkursu Daj się poznać. Postanowiłem wziąć w nim udział tworząc projekt programu do rozwiązywania obrazków logicznych (nonogramów). Umożliwi on wczytanie i samodzielne rozwiązywanie obrazków logicznych bądź skorzystanie z automatycznego solvera. Solver ten będzie rozwiązywał obrazki tak jak człowiek. Program będzie rozwiązywał obrazek stosując odpowiednie, zgodne z zasadami metody rozwiązywania. Sprawdzi czy obrazek jest możliwy do rozwiązania przez człowieka. Będzie też możliwość zweryfikowania czy istnieje tylko jedno poprawne rozwiązanie. Wprowadzanie obrazka do programu będzie odbywało się przez wpisanie liczb opisujących obrazek, narysowanie go lub poprzez import pliku z obrazkami lub bazą obrazków.

Zastosowane technologie

Część logiki solvera miałem wcześniej napisaną w języku C++, więc postanowiłem użyć właśnie tego języka i poznać jakąś biblioteką GUI. Biblioteki, które wybrałem to wxWidgets oraz QT – jeszcze nie jestem ostateczne zdecydowany na którąś z nich. Zaletą wxWidgets jest bardziej liberalna licencja i to, że kiedyś napisałem kilka bardzo prostych programów z jej użyciem, natomiast QT jest dostarczany z gotowym, skonfigurowanym środowiskiem – QT Creator i jest używany w komercyjnych projektach. Pakiet QT zawiera wszystkie niezbędne biblioteki, edytor kodu źródłowego oraz wizualny edytor plików *.ui z widokami. Wymaga jedynie dostępu do kompilatora – w moim przypadku użyję Visual C++ 14 zawartego w Visual studio 2015.