PerfectVector
Autor: Claire Yoon8 min czytania

SVG w Qt: wybierz renderer, a potem sprawdź plik

Użyj QSvgWidget lub QSvgRenderer do obsługi SVG w Qt, sprawdź aktualną obsługę funkcji i unikaj mylenia skalowalnego źródła z obrazem rastrowym o stałym rozmiarze w aplikacji.

Na tej stronie

Aby wyświetlić rysunek SVG w aplikacji Qt Widgets, zacznij od QSvgWidget. Użyj QSvgRenderer, gdy potrzebujesz narysować go na wybranej powierzchni docelowej. To rozróżnienie ma znaczenie: jednorazowe narysowanie do obiektu QImage o stałym rozmiarze daje Ci piksele do wyświetlenia, natomiast zachowanie SVG pozwala ponownie wyrenderować go w innym rozmiarze. Przewodnik po renderowaniu w Qt opisuje oba sposoby.

Najpierw wybierz sposób wyświetlania, a potem sprawdź grafikę. Podgląd w przeglądarce może pokazać zamierzony wygląd, ale nie dowodzi, że Qt obsługuje każdą funkcję użytą w pliku.

Wybierz sposób wyświetlania, zanim zaczniesz edytować SVG

Twoje zadaniePunkt wyjściaCo sprawdzić
Wyświetlenie statycznego SVG obok innych widżetówQSvgWidgetWczytywanie pliku, granice rysunku i proporcje
Rysowanie we własnym widżecie lub obrazieQSvgRenderer z obiektem rysującymRozmiar docelowy i moment renderowania
Edycja pojedynczych punktów grafiki wektorowejEdytor grafiki lub osobna implementacja edycjiEdytowalna geometria źródłowa i zachowanie zaznaczania

Dokumentacja Qt opisuje QSvgWidget jako widżet do wyświetlania SVG i udostępnia jego renderer przez renderer(). Widżet należy do SvgWidgets; jego zależność w CMake to Qt6::SvgWidgets. Dokumentacja klasy przyda Ci się tutaj bardziej niż stary przykład, który dodaje jedynie ogólny moduł SVG.

Wyświetlanie SVG nie tworzy edytora ilustracji. Zachowaj osobny plik źródłowy, jeśli ktoś będzie potrzebował przesunąć liść, zmienić kształt narożnika lub kolor oddzielnego detalu.

Schemat grafiki liścia rozdzielający się na renderowanie w widżecie i tworzenie obrazu rastrowego o stałym rozmiarze
Ilustracja dwóch sposobów renderowania. Zachowaj źródłowy SVG do późniejszego renderowania lub edycji; QImage utworzony w jednym rozmiarze jest wynikiem rastrowym. Ten schemat nie jest zrzutem z uruchomionej aplikacji Qt.

Wypróbuj mały plik źródłowy przed pełną ilustracją

Zapisz ten autorski rysunek jako leaf.svg. Zawiera liść z wypełnieniem, jasny nerw liścia i osobne koło w kolorze koralowym:

<svg xmlns="http://www.w3.org/2000/svg" width="160" height="100" viewBox="0 0 160 100">
  <path d="M24 78C20 34 56 18 98 26C90 62 58 86 24 78Z" fill="#176b64"/>
  <path d="M28 74L78 38" fill="none" stroke="#fff6e8" stroke-width="5"/>
  <circle cx="126" cy="26" r="10" fill="#ec785e"/>
</svg>

Szeroki obszar rysunku jest celowy. Jeśli liść stanie się wysoki i wąski, sprawdź obsługę proporcji, zanim zaczniesz edytować jego krzywe. Jeśli koło zniknie, sprawdź granice widocznego obszaru i porównaj wczytany plik ze źródłem. Ten mały przykład zawiera rozpoznawalne detale bez korzystania z przycinania ani efektów.

Więcej o samym pliku dowiesz się z przewodnika po formacie SVG, który wyjaśnia różnicę między kształtami wektorowymi a plikiem SVG zawierającym bitmapę.

Minimalny przykład dla Qt 6 Widgets

Utwórz main.cpp:

#include <QApplication>
#include <QSvgRenderer>
#include <QSvgWidget>
 
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    if (argc != 2)
        return 1;
 
    QSvgWidget view;
    view.load(QString::fromLocal8Bit(argv[1]));
    if (!view.renderer()->isValid())
        return 2;
 
    view.renderer()->setAspectRatioMode(Qt::KeepAspectRatio);
    view.resize(400, 240);
    view.show();
    return app.exec();
}

Przekaż nazwę pliku SVG jako argument programu, najlepiej jako ścieżkę bezwzględną na czas testów. Kod zakończenia 1 oznacza, że ten przykład nie otrzymał dokładnie jednej nazwy pliku; 2 oznacza, że renderer nie zgłosił poprawnego dokumentu. Te kody zostały wybrane na potrzeby tego przykładu i nie należą do API kodów błędów Qt.

isValid() sprawdza wczytany dokument. Nie jest testem poprawności wyglądu. Jawne ustawienie KeepAspectRatio poleca rendererowi zachowanie proporcji; dokumentacja QSvgRenderer opisuje sprawdzanie poprawności i tryby obsługi proporcji.

Umieść ten plik CMakeLists.txt obok pliku źródłowego:

cmake_minimum_required(VERSION 3.16)
project(LeafPreview LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
 
find_package(Qt6 REQUIRED COMPONENTS Widgets Svg SvgWidgets)
add_executable(leaf_preview main.cpp)
target_link_libraries(leaf_preview PRIVATE Qt6::Widgets Qt6::Svg Qt6::SvgWidgets)

Przykład jest linkowany z modułem Widgets na potrzeby aplikacji, z modułem SvgWidgets na potrzeby widżetu wyświetlającego oraz z modułem Svg na potrzeby wywołań jego renderera. Qt wymienia komponent Svg renderera oddzielnie od komponentu SvgWidgets.

Skonfiguruj i zbuduj przykład przy użyciu zainstalowanego zestawu deweloperskiego Qt 6, a następnie uruchom leaf_preview ze ścieżką do leaf.svg. To przykład kodu źródłowego oparty na dokumentacji; nie skompilowaliśmy go ani nie uruchomiliśmy w natywnym środowisku Qt. Przetestuj rzeczywistą kompilację i grafikę w systemie docelowym, zanim zaczniesz z niego korzystać.

Sprawdź aktualną obsługę funkcji, zamiast zakładać zgodność z przeglądarką

Współczesny moduł Qt SVG nie ogranicza się wyłącznie do statycznych funkcji SVG Tiny. Dokumentacja Qt opisuje dodatkowe elementy dostępne od Qt 6.7, domyślnie uwzględniane podczas parsowania, oraz opcję ograniczenia parsowania do funkcji Tiny. Dokumentacja rozszerzonych funkcji wymienia obsługiwane dodatki i ich ograniczenia.

Jednym z konkretnych ograniczeń jest clipPath: ta sama strona oznacza go jako nieobsługiwany. Dlatego plik oparty na przycinaniu wymaga sprawdzenia źródła, nawet jeśli wygląda poprawnie w przeglądarce. Wybrane maski i filtry mają udokumentowaną obsługę, ale nie oznacza to obsługi każdego efektu lub ustawienia eksportu.

Gdy prosty liść działa, ale większa ilustracja wygląda inaczej, utwórz kopię i usuwaj po jednej podejrzanej funkcji. W przypadku przycinanej grafiki rozważ utworzenie docelowej widocznej geometrii w edytorze zamiast polegania na operacji przycinania. Porównaj uzyskany kontur z oryginałem, zanim zastąpisz plik źródłowy.

Tekst wymaga osobnego sprawdzenia. Jeśli napisy się zmieniają, skorzystaj z przewodnika po rozwiązywaniu problemów z fontami w SVG. Zamiana napisów na kształty jest kompromisem projektowym; nie powinna być pierwszym sposobem naprawy nieprawidłowej nazwy pliku lub brakującego modułu.

Zauważ, kiedy proces przetwarzania zamienia SVG w piksele

Załóżmy, że Twój kod jednorazowo renderuje liść do małego obiektu QImage, tworzy z tego obrazu pixmapę, a później ją powiększa. Powiększenie działa na wyniku rastrowym. Źródłowy SVG nie zniknął, ale ta późniejsza operacja wyświetlania nie korzysta już z niego do ponownego renderowania.

Przewodnik po renderowaniu w Qt rozróżnia rysowanie do obrazu od rysowania w zdarzeniu rysowania widżetu. Jeśli obszar wyświetlania zmienia rozmiar, zdecyduj, gdzie SVG ma zostać ponownie wyrenderowany. Nie traktuj bitmapy zapisanej w pamięci podręcznej jako dowodu, że samo źródło nie może się skalować.

To samo rozróżnienie ma znaczenie podczas przygotowywania zestawu ikon SVG. Zachowaj spójne granice obszaru rysunku w plikach źródłowych, a następnie oceń każdą ikonę w rozmiarze, w którym będzie rzeczywiście używana. Rozpoznawalny duży liść nadal może stracić nerw lub osobne koło, gdy zostanie wyświetlony w małym rozmiarze.

Sprawdź wynik, zanim zaczniesz wszystko upraszczać

Zacznij od pliku, który rzeczywiście wczytujesz, a nie od innego eksportu o podobnej nazwie. Potwierdź, że prosty przykład się wyświetla, a następnie porównaj docelową grafikę w zamierzonym rozmiarze i po zmianie rozmiaru.

W przypadku liścia sprawdź, czy koło pozostaje oddzielne, nerw jest nadal widoczny, a szeroki obszar rysunku nie rozciąga grafiki. To kryteria akceptacji do sprawdzenia podczas samodzielnego uruchomienia aplikacji, a nie wyniki podane przez nas. Jeśli cały widok jest pusty, lista kontrolna dla pustego SVG pomoże odróżnić problemy z niewidoczną grafiką i granicami rysunku od problemów z konfiguracją aplikacji.

Zachowaj zdjęcia lub ilustracje z teksturami jako zasoby rastrowe, jeśli odpowiada to projektowi. Wybór SVG powinien odpowiadać na potrzeby dotyczące grafiki; sam w sobie nie zapewnia mniejszych plików, szybszego renderowania ani identycznego wyniku w różnych silnikach.

Odtwórz plik źródłowy, gdy pozostał tylko obraz rastrowy

Jeśli ikona zachowała się tylko jako PNG lub JPG, proces konwersji obrazu na grafikę wektorową w PerfectVector może pomóc przygotować edytowalną grafikę SVG przed przekazaniem jej do Qt. Po konwersji sprawdź kontur, przerwy i oddzielne detale, a następnie przetestuj SVG wybranym sposobem w Qt. Wektoryzacja przygotowuje geometrię; nie dodaje funkcji renderera ani nie zamienia widżetu wyświetlającego w edytor ścieżek.

Jeśli masz już poprawny wektorowy plik źródłowy, zmodyfikuj go bezpośrednio. Upraszczaj kopię tylko wtedy, gdy konkretna funkcja lub detal w małym rozmiarze wymaga uwagi, i zachowaj bogatsze źródło do przyszłych edycji.

Często zadawane pytania

Czy użyć QSvgWidget, czy QSvgRenderer? Użyj QSvgWidget, aby wyświetlić SVG w interfejsie Widgets. Użyj QSvgRenderer, gdy potrzebujesz kontroli nad rysowaniem na wybranej powierzchni docelowej, takiej jak własny widżet lub obraz.

Czy obecna wersja Qt obsługuje tylko SVG Tiny? Dokumentacja Qt opisuje obsługę statycznego SVG Tiny oraz wybranych rozszerzeń wprowadzonych w Qt 6.7. Sprawdź aktualną dokumentację funkcji i skonfigurowane opcje, zamiast zakładać obsługę wyłącznie Tiny lub zgodność z przeglądarką.

Dlaczego SVG może wyglądać na rozmyty po umieszczeniu go w pixmapie? Jeśli najpierw wyrenderujesz go do obrazu rastrowego o stałym rozmiarze, powiększanie tego wyniku skaluje piksele. Sprawdź ponownie powierzchnię docelową renderowania i to, czy SVG jest ponownie renderowany w wymaganym rozmiarze.

Czy poprawne wczytanie SVG dowodzi, że każdy detal został prawidłowo wyrenderowany? Nie. Sprawdzenie poprawności nie zastępuje oceny wizualnej. Porównaj granice rysunku, proporcje, drobne detale i obsługiwane funkcje w rzeczywistej aplikacji docelowej.

Źródła

  1. Qt — Rendering SVG Files — Widżety wyświetlające, powierzchnie docelowe rysowania oraz rozróżnienie między renderowaniem w widżecie a pośrednimi obrazami rastrowymi.
  2. Qt — QSvgWidget Class — Widżet wyświetlający, dostęp do renderera i zależność SvgWidgets.
  3. Qt — QSvgRenderer Class — Zależność Svg, poprawność dokumentu i ustawienia proporcji.
  4. Qt — Extended Features — Współczesne rozszerzenia i jawne ograniczenia funkcji, w tym nieobsługiwane ścieżki przycinania.

Zacznij od jednego małego pliku i sprawdź go wybranym sposobem w Qt. Jeśli grafika rastrowa wymaga odtworzenia, przygotuj edytowalny plik SVG do sprawdzenia, porównaj kształty ze źródłem i ponów sprawdzenia w aplikacji, zanim zastąpisz swój zasób.

Więcej z bloga

Zacznij od czystszego SVG,
który łatwiej edytować