pdfviewer — u_pbt_pdfviewer #
← Référence des composants · Sommaire du guide
Visionneuse PDF intégrée : affiche un document local ou publié sur le web, directement dans votre fenêtre, avec pagination, zoom et impression.
▶ Le voir en vrai — Application de démonstration, tuile PDF viewer : l'aperçu, le code qui le produit et cette page, côte à côte.
En bref #
| Userobject | u_pbt_pdfviewer |
| Classe d'items | — (composant sans items) |
| Sert à | Afficher une facture, un bon de commande, un contrat ou une notice sans lancer d'application externe |
| Options opt-in | — |
Le composant remplace le classique « enregistrer le PDF dans un fichier temporaire puis appeler ShellExecute » : le document reste dans votre application, l'utilisateur ne quitte jamais l'écran en cours.
Démarrage rapide #
// event open de la fenetre : afficher un document present sur le disque
uo_pdf.is_source = "C:\factures\FA-2026-0142.pdf"
// event ue_load_completed de uo_pdf : (string as_source)
uo_status.of_panel(/*key*/ "main").is_text = "Document affiche"
C'est tout : poser is_source suffit à charger et afficher le document.
Propriétés #
| Propriété | Type | Défaut | Rôle |
|---|---|---|---|
is_source | string | "" | Document à afficher : un chemin de fichier (absolu, relatif à l'application ou réseau ; un # fait partie du nom), une adresse file:///, une adresse web https://… servie en application/pdf, ou une adresse data:application/pdf. Poser la valeur déclenche le chargement ; poser "" (ou des espaces seuls) vide la visionneuse en gardant ses réglages. Tout le reste est refusé et signalé par ue_load_failed — http:// compris, et une adresse qui porte un nom d'utilisateur et un mot de passe (https://nom:secret@…). Un PDF tenu dans un blob s'affiche par of_load_blob. Se relit tel que vous l'avez écrit |
ii_page | integer | 0 | Page d'ouverture, comptée à partir de 1 (0 = la première page du document). Posée pendant qu'un document est affiché, c'est sa page : il se recharge, ouvert dessus. Posée quand la visionneuse est vide, elle vaut pour le document suivant ; sinon un nouveau document s'ouvre à sa première page. Pour ouvrir un document sur une page, posez is_source puis ii_page : un seul chargement. Chaque changement recharge le document et relève ue_load_completed : le lecteur ne lit sa page qu'au chargement ; la même valeur reposée ne fait rien. En écriture seule : la relire donne la dernière page demandée, pas celle affichée. Le lecteur est celui du moteur web, il ne rend compte de rien. |
ii_zoom | integer | 0 | Zoom en pourcentage, de 25 à 500 — la plage des boutons du lecteur (0 = laissé au lecteur). Une valeur hors de cette plage y est ramenée, et se relit telle qu'appliquée. Poser un zoom annule is_fit, qui le contredit. En écriture seule, comme ii_page : si l'utilisateur zoome avec la barre du lecteur, cette propriété ne suit pas. |
is_fit | string | "" | Ajustement : FIT_PAGE, FIT_WIDTH, FIT_HEIGHT, ou "" pour aucun. Annule ii_zoom |
ib_viewer_toolbar | boolean | true | Affiche la barre du lecteur (sommaire, numéro de page, zoom, rotation, recherche, impression, enregistrement). Masquez-la quand votre fenêtre porte elle-même ces commandes. Le lecteur intégré à WebView2 n'a pas de commande Plein écran |
is_destination | string | "" | Ouvre le document sur une destination nommée du PDF — la cible d'un signet, écrite par l'outil qui a produit le fichier. "" pour aucune ; un nom que le document n'a pas l'ouvre à sa première page. Gardée pour les documents suivants tant que vous ne la changez pas. Chaque changement recharge le document affiché |
ib_allow_save | boolean | true | Offre les commandes Enregistrer et Enregistrer sous de la barre du lecteur et de son menu. À false, le document est montré sans proposer d'en sauver une copie. Chaque visionneuse garde son réglage : celui d'une autre fenêtre n'y change rien. Ce n'est pas une protection : le fichier reste lisible sur le disque. Chaque changement recharge le document affiché ; posé avant is_source, le document ne se charge qu'une fois |
ib_allow_print | boolean | true | Offre la commande Imprimer de la barre du lecteur et de son menu. of_print imprime toujours : c'est votre application qui décide. Chaque visionneuse garde son réglage. Chaque changement recharge le document affiché ; posé avant is_source, le document ne se charge qu'une fois |
ib_allow_search | boolean | true | Offre la commande Rechercher de la barre du lecteur. La recherche appartient à l'utilisateur (aussi par Ctrl+F) : le lecteur n'offre aucune recherche pilotée par votre application. Chaque visionneuse garde son réglage. Chaque changement recharge le document affiché ; posé avant is_source, le document ne se charge qu'une fois |
ib_allow_rotate | boolean | true | Offre la commande Faire pivoter de la barre du lecteur. Chaque visionneuse garde son réglage. Chaque changement recharge le document affiché ; posé avant is_source, le document ne se charge qu'une fois |
ib_allow_navigation_pane | boolean | true | Offre le bouton Sommaire de la barre du lecteur, en haut à gauche : il ouvre le panneau latéral avec les signets et les vignettes des pages. À false, le bouton disparaît. Que le panneau soit ouvert est l'affaire du lecteur et de l'utilisateur : votre application offre le bouton ou non. Chaque visionneuse garde son réglage. Chaque changement recharge le document affiché ; posé avant is_source, le document ne se charge qu'une fois |
is_theme_style | string | "" | Style visuel de la surface propre au composant : ce que la visionneuse montre quand elle ne tient aucun document (avant le premier, après is_source = "" ou un document refusé). Le lecteur PDF garde son allure : il suit le thème de l'application (PBT_SetDefaultTheme), en clair ou sombre seulement, car WebView2 donne à tous ses lecteurs PDF un même jeu de couleurs. Vide = le style de l'application, suivi à chaque changement |
is_theme_mode | string | "" | Variante claire ou sombre de la surface propre au composant, visible quand la visionneuse ne tient aucun document. Le lecteur PDF ne la suit pas : sa barre et ses marges prennent le clair ou le sombre du thème de l'application (PBT_SetDefaultTheme). Vide = celle de l'application, suivie à chaque changement |
il_theme_accent | long | -1 | Couleur d'accent de ce composant (-1 = l'accent de l'application, ou celui du thème). Sans effet visible ici : ni le lecteur PDF ni la visionneuse vide ne dessinent avec un accent. La valeur est gardée et se relit telle que posée |
Méthodes #
| Méthode | Rôle |
|---|---|
of_refresh ( ) | Relit le document courant (sur le disque ou le réseau) sans toucher aux réglages : le moyen d'afficher un fichier régénéré au même chemin. La position de défilement n'est pas gardée : le lecteur repart à ii_page. Après un échec, retente le même document. Un document refusé est jugé de nouveau : ue_load_failed est relevé. Renvoie 0 une fois demandé, -4 sans document (is_source vide), -2 si le composant n'est pas créé |
of_load_blob (blob ablb_pdf) · of_load_blob (blob ablb_pdf, string as_name) | Affiche un PDF tenu dans un blob — lu en base (SELECTBLOB) ou reçu d'un service — sans écrire de fichier, quelle que soit sa taille : les octets restent en mémoire et ne sont servis qu'à cette visionneuse. Le second argument est le nom que relisent is_source et ue_load_completed / ue_load_failed (document.pdf sans lui). Le blob affiché avant est libéré, celui-ci l'est par le document suivant ou of_reset. Renvoie 0 une fois demandé (ue_load_completed suit), -5 si le blob est vide ou n'est pas un PDF, -4 s'il est trop gros pour ce processus (64 Mo en 32 bits, 512 Mo en 64 bits) — is_last_error dit pourquoi —, -2 si le composant n'est pas créé |
of_print ( ) · of_print (boolean) | Ouvre l'aperçu d'impression du document — pas de la page qui l'encadre. Renvoie 0 une fois l'aperçu demandé, -4 quand aucun document n'est affiché, -2 si le composant n'est pas créé. L'argument est sans effet ici : c'est toujours l'aperçu du lecteur PDF |
of_print_to_pdf (string) · of_print_to_pdf (string, boolean) | Rend -4 sur ce composant, sans rien écrire : la page imprimée ne serait que le cadre du lecteur, jamais le document. Le document est déjà un PDF : copiez le fichier de is_source |
of_reset ( ) | Vide la visionneuse et remet toutes les propriétés à leur défaut. Renvoie 0 une fois appliqué, -2 si le composant n'est pas créé |
of_set_redraw (boolean) | Regroupe une rafale de modifications en un seul rendu. Renvoie 0 une fois appliqué, -2 si le composant n'est pas créé |
of_save_as_png (string) · of_save_as_jpg (string) | Exporte le rendu en image. Renvoie 0 une fois l'image écrite, -4 si l'écriture échoue, -2 si le composant n'est pas créé |
Événements #
| Événement | Déclenché quand |
|---|---|
ue_load_completed (string as_source) | Le document est affiché ; as_source est is_source tel que vous l'avez écrit (pour un blob, le nom donné à of_load_blob). Relevé aussi par of_refresh et par chaque changement de page, de zoom, d'ajustement, de barre du lecteur, de destination ou d'une commande ib_allow_* — posez-les avant is_source pour un seul chargement ; la même valeur reposée ne le relève pas. Jamais levé sur un échec |
ue_load_failed (string as_source, string as_reason) | Le document n'a pas pu être affiché ; as_reason est l'une des constantes REASON_* ci-dessous. La visionneuse reste vide |
ue_link_clicked (string as_url) | L'utilisateur a suivi un lien du document. La visionneuse reste sur le document : ouvrez as_url où vous voulez (navigateur du poste, webbrowser…). as_url est l'adresse du lien telle quelle (https://…, mailto:…) ; un lien relatif d'un document local arrive en chemin disque. Un lien vers un fichier local du poste (file:///) dans un PDF n'est pas suivi : le lecteur de PDF de WebView2 le bloque ; aucun ue_link_clicked n'est levé |
ue_ready ( ) | Le composant a fini de charger ; tout ce qui a été envoyé avant a été rejoué |
ue_runtime_missing ( ) | Le runtime WebView2 est absent : le composant reste vide |
ue_bg_color (long al_color) | Le composant a calculé sa couleur de fond de thème ; l'userobject l'a déjà adoptée (backcolor) |
Pourquoi un document n'est pas affiché #
as_reason de ue_load_failed est l'une de ces constantes de u_pbt_pdfviewer. Un PDF se reconnaît ainsi : un fichier local porte l'extension .pdf et commence par la signature %PDF- ; un document distant est servi avec le type application/pdf (le seul que le moteur remet à son lecteur) ; une adresse data: annonce application/pdf.
| Constante | Valeur | Cause |
|---|---|---|
REASON_NOT_FOUND | "notfound" | Fichier absent ou illisible, adresse qui répond 404 |
REASON_NOT_PDF | "notpdf" | Ce n'est pas un PDF : fichier local sans la signature %PDF-, réponse distante qui n'est pas application/pdf (un serveur de fichiers qui répond application/octet-stream : téléchargez le document d'abord, voir les exemples), data: ou blob d'un autre type |
REASON_TOO_LARGE | "toolarge" | Fichier trop gros pour ce processus (au-delà de 64 Mo en 32 bits, 512 Mo en 64 bits), ou adresse data: de plus de 2 Mo de caractères (environ 1,5 Mo de PDF) |
REASON_INSECURE | "insecure" | http:// : non pris en charge, servez le document en https:// |
REASON_UNSUPPORTED | "unsupported" | Une autre sorte d'adresse (ftp:, blob:…), ou une adresse qui porte un nom d'utilisateur et un mot de passe (https://nom:secret@…) |
REASON_NETWORK | "network" | Serveur injoignable, nom inconnu, connexion coupée |
REASON_CERTIFICATE | "certificate" | Certificat du site invalide, expiré ou révoqué |
REASON_AUTH | "auth" | Le site ou le proxy demande une authentification : téléchargez le document par le restclient (jeton, identifiants), puis affichez-le (voir les exemples) |
REASON_HTTP | "http" | Une autre erreur du serveur (403, 500…) |
REASON_REFUSED | "refused" | Le site refuse d'être affiché dans un cadre, ou envoie le PDF en téléchargement — le fichier n'est pas téléchargé pour autant |
REASON_FAILED | "failed" | Toute autre cause |
Ce que l'utilisateur peut faire, sans une ligne de code #
La visionneuse affiche sa barre d'outils intégrée au-dessus du document. Vous n'avez rien à programmer : elle est fournie et localisée par le système.
| Action | Comment |
|---|---|
| Pagination | Molette et barre de défilement, ou saisie directe du numéro de page dans le compteur n / total |
| Zoom | Boutons + / −, ajustement à la page ou à la largeur |
| Recherche | Bouton de recherche de la barre d'outils, dans le texte du document |
| Impression | Bouton imprimante de la barre d'outils (masquable par ib_allow_print), ou of_print depuis votre code |
| Enregistrement | Bouton de téléchargement, pour sauver une copie du document (masquable par ib_allow_save) |
| Rotation | Rotation des pages depuis le menu de la barre d'outils |
| Clavier | Dès que le composant a le focus (Tab ou of_focus_webview) : PageDown, flèches, Début / Fin font défiler le document, sans clic préalable |
Les raccourcis du navigateur — Ctrl+F, Ctrl+P, Ctrl + molette — sont coupés dans tous les composants, celui-ci compris : passez par les boutons de la barre du lecteur.
Ce que le lecteur ne dit pas #
Le lecteur est celui qui est intégré au moteur web : aucune dépendance à installer, l'impression, la recherche et les formulaires PDF fournis. En contrepartie, il ne rend compte de rien à votre application : ni la page affichée, ni le nombre de pages, ni le zoom réel, ni le texte sélectionné, et la recherche ne se pilote pas par code : le lecteur ignore les paramètres d'ouverture qui surligneraient un texte ou ouvriraient son panneau latéral. Il n'a pas de commande Plein écran, et il suit le thème clair ou sombre de l'application, jamais celui du composant. ii_page et ii_zoom disent où ouvrir le document, pas où l'utilisateur se trouve. Un PDF protégé par un mot de passe : le lecteur le demande lui-même à l'utilisateur, votre application ne peut pas le lui fournir. Ce choix est délibéré ; un rendu scriptable demanderait une bibliothèque externe.
Exemples #
Ouvrir un document local #
// Chemin absolu, ou relatif au repertoire de l'application
uo_pdf.is_source = "doc\conditions-generales.pdf"
Ouvrir un document publié sur le web #
// Une adresse web se charge exactement comme un fichier local
uo_pdf.is_source = "https://www.monsite.fr/tarifs/catalogue-2026.pdf"
Une connexion internet est évidemment nécessaire ; le chargement est asynchrone, ue_load_completed vous signale la fin.
Afficher le PDF que vient de produire une DataWindow #
// Local variables
string ls_file
// Un fichier par jour, dans le dossier temporaire
ls_file = "C:\temp\report_" + String(Today(), "yyyymmdd") + ".pdf"
// La DataWindow produit le fichier...
dw_report.SaveAs(ls_file, PDF!, false)
// ...et la visionneuse l'affiche immediatement
uo_pdf.is_source = ls_file
Rafraîchir après régénération du fichier #
// Le fichier a ete reecrit au meme emplacement : recharger sans retoucher is_source
uo_pdf.of_refresh()
Enchaîner plusieurs documents dans la même visionneuse #
// event rowfocuschanged de dw_list : (long currentrow)
// Local variables
string ls_pdf
// Le chemin du PDF de la ligne courante
ls_pdf = dw_list.GetItemString(currentrow, "pdf_path")
// Sans piece, la visionneuse se vide (ses reglages gardes) ; sinon elle l'affiche
if ls_pdf = "" then
uo_pdf.is_source = ""
else
uo_pdf.is_source = ls_pdf
end if
Suivre la fin du chargement #
// event ue_load_completed de uo_pdf : (string as_source)
uo_wait.Hide()
// of_print imprime le document affiche
uo_print_button.ib_enabled = true
Dire pourquoi le document n'est pas là #
// event ue_load_failed de uo_pdf : (string as_source, string as_reason)
uo_wait.Hide()
choose case as_reason
case uo_pdf.REASON_NOT_FOUND
uo_status.of_panel(/*key*/ "main").is_text = "Document introuvable : " + as_source
case uo_pdf.REASON_NOT_PDF
uo_status.of_panel(/*key*/ "main").is_text = "Ce fichier n'est pas un PDF"
case else
uo_status.of_panel(/*key*/ "main").is_text = "Document indisponible (" + as_reason + ")"
end choose
Ouvrir ailleurs un lien du document #
// event ue_link_clicked de uo_pdf : (string as_url)
// La visionneuse reste sur le document : le lien s'ouvre dans le navigateur de la fenetre
uo_web.is_address = as_url
Imprimer le document #
// clicked du bouton Imprimer : l'apercu du lecteur PDF, sur le document lui-meme
if uo_pdf.of_print() = -4 then
uo_status.of_panel(/*key*/ "main").is_text = "Aucun document a imprimer"
end if
Montrer sans laisser enregistrer ni imprimer #
// Un document confidentiel : ni Enregistrer ni Imprimer dans la barre du lecteur
uo_pdf.ib_allow_save = false
uo_pdf.ib_allow_print = false
uo_pdf.is_source = is_current_document
Posez-les avant is_source : le document ne se charge qu'une fois. Chaque visionneuse garde son réglage. Ce n'est pas une protection : le fichier reste lisible sur le disque, et of_print imprime toujours.
Aperçu dans un onglet, à côté de la saisie #
// event open : la visionneuse occupe une page d'onglet, la saisie l'autre
uo_tab.of_add_page(/*key*/ "entry", /*title*/ "Saisie", /*page*/ uo_page_entry)
uo_tab.of_add_page(/*key*/ "preview", /*title*/ "Apercu", /*page*/ uo_page_preview)
// La visionneuse est posee dans uo_page_preview comme n'importe quel controle
uo_pdf.is_source = is_current_document
Le composant s'héberge sans précaution particulière dans un tab ou un panneau dockcontainer.
Vérifier le fichier avant de l'afficher #
// Local variables
string ls_path
// Le fichier de la facture affichee
ls_path = "C:\factures\" + is_number + ".pdf"
// Pas de fichier, rien a montrer : on vide la visionneuse plutot que de laisser l'ancien document
if not FileExists(ls_path) then
uo_pdf.is_source = ""
uo_status.of_panel(/*key*/ "main").is_text = "Facture introuvable"
return
end if
// Sinon, la facture s'affiche
uo_pdf.is_source = ls_path
Afficher un PDF lu en base (blob) #
// Local variables
blob lblb_pdf
// La facture rangee en base, lue dans un blob
SELECTBLOB pdf_file INTO :lblb_pdf FROM invoice WHERE invoice_no = :is_number USING SQLCA;
// Affichee directement depuis la memoire : aucun fichier temporaire, quelle que soit sa taille
if SQLCA.SQLCode = 0 then
uo_pdf.of_load_blob(/*pdf*/ lblb_pdf, /*name*/ "invoice-" + is_number + ".pdf")
end if
Le nom donné revient dans is_source et dans ue_load_completed ; le blob est libéré par le document suivant ou par of_reset.
Ouvrir sur un chapitre #
// Ouvert sur le chapitre "prices" du catalogue ; le bouton Sommaire du lecteur liste les signets
uo_pdf.is_destination = "prices"
uo_pdf.is_source = "doc\catalogue-2026.pdf"
Le nom d'une destination est celui que l'outil qui a produit le PDF a écrit : votre générateur de documents le connaît.
Un document derrière un jeton, ou servi en octet-stream #
// Local variables
long ll_status
string ls_file
// Le restclient (inv_rest, prepare a l'ouverture de la fenetre) envoie le jeton et telecharge le fichier
ls_file = "C:\temp\invoice-4152.pdf"
ll_status = inv_rest.of_download(/*url*/ "/orders/4152/invoice.pdf", /*path*/ ls_file)
// Puis la visionneuse affiche le fichier, quel que soit le type annonce par le serveur
if ll_status = 200 then
uo_pdf.is_source = ls_file
end if
Le lecteur du moteur ne sait ni envoyer un jeton ni afficher une réponse application/octet-stream (REASON_AUTH, REASON_NOT_PDF) : le restclient le fait pour lui.
Formats et chemins acceptés #
Forme de is_source | Exemple | Remarque |
|---|---|---|
| Chemin absolu | "C:\docs\contrat.pdf" | Le plus fiable |
| Chemin relatif | "doc\notice.pdf" | Relatif au répertoire de l'application |
| Chemin réseau | "\\serveur\partage\bon.pdf" | L'utilisateur doit avoir les droits de lecture |
Nom avec # | "C:\devis\Devis #12.pdf" | Le # fait partie du nom du fichier |
Adresse file: | "file:///C:/docs/contrat.pdf" | Convertie en chemin, comme un chemin absolu ; file://localhost/C:/… et la forme UNC à quatre barres file:////serveur/partage/… aussi |
| Adresse web | "https://…/catalogue.pdf" | Servie en application/pdf, chargement asynchrone. Un #page=… écrit dans l'adresse est ignoré : utilisez ii_page. Une adresse qui porte des identifiants (https://nom:secret@…) est refusée (REASON_UNSUPPORTED) : passez par le restclient |
| Document en mémoire | "data:application/pdf;base64,…" | Rien n'est écrit sur le disque. Au-delà de 2 Mo de caractères (environ 1,5 Mo de PDF), ue_load_failed avec REASON_TOO_LARGE : pour un document en mémoire plus gros, of_load_blob |
Adresse http:// | "http://intranet/bon.pdf" | Non prise en charge : ue_load_failed avec REASON_INSECURE. Servez le document en https:// |
| Vide | "" | Vide la visionneuse et garde ses réglages ; une valeur faite d'espaces aussi |
Seul le PDF est pris en charge par ce composant : ce qui n'en est pas un est refusé et signalé par ue_load_failed (REASON_NOT_PDF). Pour une image, utilisez picture ; pour une page HTML, webbrowser.
Bonnes pratiques #
- Surveillez
ue_load_failed: un chemin invalide, un fichier qui n'est pas un PDF ou un site injoignable y est signalé avec sa raison, et la visionneuse reste vide. - Pour vider la visionneuse (changement de ligne sans pièce jointe), posez
is_source = "": sinon le document précédent reste visible.of_reset()la vide aussi, mais remet en plus tous les réglages à leur défaut — Enregistrer et Imprimer compris. of_refresh()est le moyen d'afficher un fichier régénéré au même chemin : il relit le fichier sans toucher aux réglages. Il ne garde pas la position de défilement — le lecteur repart àii_page.- Chaque changement de
ii_zoom,is_fit,ib_viewer_toolbar,is_destination,ib_allow_saveouib_allow_printrecharge le document (le lecteur ne lit ses réglages qu'au chargement) et relèveue_load_completed: posez-les avantis_sourcepour un seul chargement. La même valeur reposée ne recharge rien.ii_pageposé pendant qu'un document est affiché vaut pour ce document : pour en ouvrir un autre sur une page, posezis_sourcepuisii_page. - Prévoyez un indicateur d'attente pour les documents distants ou volumineux, et masquez-le sur
ue_load_completedet surue_load_failed. - Donnez au composant une surface confortable (au moins la moitié de la fenêtre) : la barre d'outils intégrée et le document ont besoin de place pour rester lisibles.
- Pour afficher une page web plutôt qu'un PDF, utilisez webbrowser ; pour une image, picture.
Hérité du socle commun #
Ces membres existent sur tous les composants visuels — ils ne sont pas propres à celui-ci. Ils sont détaillés une seule fois, dans les chapitres transverses ; cette table dit seulement où les lire.
| Membres | Rôle | Détaillé dans |
|---|---|---|
of_reset | Remettre le composant à zéro | 3.6 Remettre un composant à zéro : of_reset() |
of_register_shortcut · of_clear_shortcuts | Raccourcis clavier du composant | 3.5 Les raccourcis clavier |
ib_created · ib_ready · is_last_error | S'il est né, s'il est prêt, ce qui a échoué | 3.7 Diagnostic |
of_save_as_png · of_save_as_jpg | Exporter le rendu en image | 3.8 Exporter le rendu en image |
of_set_redraw | Grouper les modifications en un seul repaint | 3.10 Bonnes pratiques |
of_preload_icons | Icônes affichées sans délai | Affichage instantané : of_icon |
of_set_translation | Traduire un libellé du composant | 5.2 Adapter un libellé : of_set_translation |
of_focus_webview | Donner le focus au composant | 6.4 Clavier et focus |
of_print · of_print_to_pdf | Imprimer, ou écrire un PDF | 6.9 Imprimer |
of_set_property · of_get_property · is_component_name | Piloter une propriété par son nom | 3.1 Le moteur de propriétés |
is_accessible_name · is_accessible_description | Le nom et la description que dit un lecteur d'écran | 3.4 Propriétés et events optionnels |
Deux aides ne sont pas héritées : of_icon et of_escape_markup vivent sur n_pbt_utils. Déclarez-en une — n_pbt_utils lnv_utils, rien à créer — et appelez-les dessus.