sobota, 3 listopada 2012

QGIS API: zastępowanie domyślnego formularza

W QuantumGIS, każdy obiekt geograficzny reprezentowany klasą QgsFeature charakteryzuje się zbiorem właściwości (atrybutów). W przypadku punktów kopiowanych przez QAZP2 do relacyjnej bazy są to na przykład nazwa punktu (nadawana przez użytkownika), rodzaj badań (lotnicze, powierzchniowe, itp.), czas rejestracji i inne. Jednym ze sposobów wprowadzania obiektów jest wskazanie myszką ich lokalizacji, a w przypadku dwuwymiarowych (np. poligonów) dodatkowo ich kształtu. W rezultacie zostaje wyświetlone okno dialogowe, w którym określa się atrybuty, o których mowa była wcześniej. W domyślnej postaci składa się ono z pól tekstowych, w których użytkownik wprowadza odpowiednie wartości. I tak się dzieje bez względu na to, czy kolumna bazy danych zawiera dane tekstowe, czy liczbowe, logiczne, albo na przykład są ograniczone do pewnego zakresu wartości (tzw. dziedziny). To zachowanie można zmienić modyfikując właściwości warstwy, nad którą pracujemy, jednak trzeba to robić dla każdego projektu z osobna. W tym artykule chciałbym przedstawić sposób na zastępowanie domyślnego okna dialogowe takim, które jest dostosowane do naszych potrzeb bez udziału użytkownika.

Przed rozpoczęciem pisania funkcji w Pythonie konieczne jest utworzenie naszego formularza. QGIS wymaga przygotowania go w postaci pliku XML z rozszerzeniem *.ui, który można wygenerować w programie QtDesigner, który jest dostarczany z biblioteką Qt. Można wtedy umieścić w oknie dialogowym różne komponenty takie jak listy rozwijane (QCombobox), pola liczbowe (QSpinBox), czy do wprowadzania wartości logicznych (QCheckbox). Trzeba przy tym pamiętać, żeby każdy z komponentów miał taką samą nazwę jak kolumna w tabeli, której odpowiada. Przykładem takiego formularza jest ten stosowany w QAZP2 do wprowadzania punktów. Jego zawartość można obejrzeć otwierając plik w dowolnym edytorze tekstu, albo w QtDesignerze.

Kluczową kwestią dla rozwiązania tego problemu zastąpienia domyślnego okna dialogowego jest uchwycenie chwili, w której interesująca nas warstwa wektorowa zostaje wczytana w programie QGIS. Aby to zrobić trzeba się odwołać do obiektu klasy qgis.core.QgsMapLayerRegistry, który można uzyskać wywołując statyczną metodę instance(). Za każdym razem, gdy użytkownik otwiera nową warstwę, emitowany jest syngnał layerWasAdded, na który musimy zareagować podejmując odpowiednią akcję. To działanie będzie reprezentowała funkcja dodajUi(warstwa) w następującej postaci:

def dodajUi(warstwa):
    if warstwa.name() == 'miejsca':
        warstwa.setEditForm(abspath(__file__+'/../forms/miejsca.ui'))


Przez parametr warstwa przekazywana jest referencja do obiektu klasy QgsVectorLayer, której wczytanie wyemitowało sygnał layerWasAdded. Jeżeli warstwa nazywa się 'miejsca', to trzeba wywołać metodę setEditForm, w której podajemy bezpośrednią ścieżkę pliku *.ui wygenerwanego w QtDesignerze. Wartość __file__ dla dowolnego modułu Pythona zwaraca jego lokalizację w systemie plików. W tym przypadku katalog 'forms', w którym znajduje się plik 'miejsca.ui' jest zapisany na tym samym poziomie co katalog z modułem, który zawiera funkcję dodajUi. Przykład implementacji funkcji dodajUi można znaleźć w module qazp.py.

Aby wskazać, jaka akcja ma być wykonana po emisji sygnału layerWasAdded, trzeba go połączyć z funkcją dodajUi, co w bibliotece Qt realizuje się wywołując sekwencję QgsMapLayerRegistry.instance().layerWasAdded.connect(dodajUi). Ta operacja jest wykonywana w chwili inicjalizacji wtyczki, która zgodnie z wymaganiami QGIS następuje w funkcji initGui w momencie uruchamiania programu albo po pierwszej instalacji nowej wtyczki. Od tej chwili, gdy użytkownik będzie próbował dodać kolejny punkt na mapie, zamiast domyślnego okna dialogowego zostanie mu wyświetlone to, które zostało zdefiniowane w pliku miejsca.ui.

Brak komentarzy:

Prześlij komentarz