Barrierefreie Softwareentwicklung mit Python und Qt6 nach EN 301 549 und WCAG 2.2

In diesem Blogartikel erkläre ich die barrierefreie Softwareentwicklung mit der Programmiersprache Python und dem  Framework Qt, dass die plattformunabhängige Entwicklung für Desktop-, Embedded- und Mobilanwendungen unterstützt.

Barrierefreie Softwareentwicklung mit Python und Qt6 nach EN 301 549 und WCAG 2.2 – um was geht in diesem Artikel?

In diesem Blogartikel erfahren Sie, wie Sie Barrierefreiheit bei Software mit der Programmiersprache Python und dem grafischen FrameWork Qt erstellen können. Ich gebe Ihnen als Experte wertvolle Tipps und Techniken, um sicherzustellen, dass Ihre Anwendungen für alle Benutzer zugänglich und nutzbar sind. Erfahren Sie mehr über die besten Praktiken für barrierefreie Softwareentwicklung und wie Python und Qt Ihnen dabei helfen kann. Starten Sie jetzt und verbessern Sie die Benutzererfahrung für alle!

Barrierefreie Softwareentwicklung – Eine Einführung

Barrierefreie Softwareentwicklung bedeutet, dass Software so gestaltet wird, dass sie von allen Menschen genutzt werden kann, unabhängig von etwaigen Behinderungen oder körperlichen Einschränkungen. In diesem Blogartikel geht es um barrierefreie Softwareentwicklung mit der Programmiersprache Python.

Barrierefreiheit bei Software sorgt dafür, dass Ihre Software und mehr Nutzer mit unterschiedlichen Behinderungen bedient werden kann. Nutzer die blind sind, Nutzer mit Sehbehinderung, Nutzer mit körperlich eingeschränkten Händen und Nutzer mit einer Farbfehlsichtigkeit können Ihre Software bedienen.

Wichtige Fakten zur Programmiersprache Python

Python ist eine populäre und leicht zu erlernende Programmiersprache, die für ihre Einfachheit und Lesbarkeit bekannt ist. Hier sind einige ihrer wichtigsten Merkmale: Einfach lesbarer Code: Python legt großen Wert darauf, dass der Code für Menschen leicht zu verstehen ist. Die Syntax ist klar und aufgeräumt, was das Schreiben und Lesen von Python-Code angenehm macht.

Vielseitigkeit: Python kann in vielen Bereichen eingesetzt werden, von der Webentwicklung über Datenanalyse bis hin zu künstlicher Intelligenz. Es gibt eine große Auswahl an Bibliotheken und Frameworks, die die Entwicklung erleichtern.

Interpretierte Sprache: Python ist eine interpretierte Sprache, was bedeutet, dass der Code zur Laufzeit direkt ausgeführt wird, ohne dass eine vorherige Kompilierung erforderlich ist. Dies macht den Entwicklungsprozess schneller und flexibler. Dynamische Typisierung: In Python müssen Variablentypen nicht explizit angegeben werden. Die Typisierung erfolgt dynamisch zur Laufzeit, was die Flexibilität erhöht und den Code kürzer macht.

Umfangreiche Standardbibliothek: Python wird mit einer umfangreichen Standardbibliothek geliefert, die viele nützliche Funktionen und Module enthält. Dadurch sind viele Aufgaben bereits mit Bordmitteln lösbar, ohne dass zusätzliche Bibliotheken installiert werden müssen.

Community und Unterstützung: Python hat eine sehr aktive und hilfsbereite Community. Es gibt unzählige Tutorials, Foren und Dokumentationen, die es einfach machen, Hilfe zu finden und schnell Antworten auf Fragen zu erhalten.

Plattformunabhängigkeit: Python läuft auf den meisten gängigen Betriebssystemen (Windows, macOS, Linux) und ist daher plattformunabhängig. Das bedeutet, dass der gleiche Code auf verschiedenen Systemen ausgeführt werden kann, ohne Änderungen vornehmen zu müssen.

Ich habe bereits mehrere barrierefreie Python-Anwendungen entwickelt, die erfolgreich auf den Betriebssystemen Windows, Ubuntu (=Linux-Distribution) und MacOS gestartet werden konnten.

Open Source: Python ist eine Open-Source-Sprache, was bedeutet, dass sie frei verfügbar ist und von einer weltweiten Gemeinschaft von Entwicklern ständig verbessert wird. Diese Eigenschaften machen Python zu einer ausgezeichneten Wahl für Entwickler aller Erfahrungsstufen, sei es für Anfänger, die das Programmieren lernen, oder für erfahrene Entwickler, die komplexe Anwendungen erstellen möchten.

Betriebssystem, Entwicklungsumgebung, Python-Version, Qt-Version

Softwareumgebung Im Einsatz
Betriebssystem Windows 11
Entwicklungsumgebung PyCharm 2024.1
Programmiersprache Python 3.12.1
Framework PyQT6

PyQt6 installieren

PyQt6 muss installiert werden. Dies kann in der Entwicklungsumgebung PyCharm im Terminal gemacht werden, mit folgendem Befehl:

pip install PyQt6

Was Programmieren wir?

Wir programmieren eine Eingabemaske in die der Anwender folgende Daten eingeben kann:

  • Vorname
  • Nachname
  • Strasse
  • Postleitzahl
  • Ort
  • Telefonnummer
  • E-Mailadresse

Eingabemaske programmiert mit der Programmiersprache Python und dem Framework Qt um Daten zu einer Person einzugeben. Zu sehen sind 7 Eingabefelder und 3 Schaltflächen

Nach welchen Richtlinien programmieren wir barrierefrei?

Was sind Richtlinien für barrierefreie Programmierung? Damit eine Software, egal mit welcher Programmiersprache sie entwickelt wird, barrierefrei programmiert werden kann bedarf es Richtlinien. Die Richtlinien sorgen dafür, dass Menschen mit unterschiedlichen Behinderungen oder anderen körperlichen Einschränkungen eine Software bedienen können. Wenn eine Software für ein europäisches Land barrierefrei programmiert wird, sollte die Richtlinie EN 301 549 verwendet werden. Hier ein Link zu den Prüfschritten der EN 301 549: BITV-Test / EN 301 549 (Web)Prüfschritte Wenn eine Software für ein nicht europäisches Land barrierefrei programmiert werden soll, sollte die Richtlinie WCAG 2.2 verwendet werden. Hier ein Link zu den Prüfschritten der WCAG 2.2: Web Content Accessibility Guidelines (WCAG) 2.2 Weil die EN 301 549 Menschen mit bestimmten körperlichen Beeinträchtigungen ausschließt, verwenden wir beide Richtlinien für unsere barrierefreie Python-Software.

Barrierefreie Softwareentwicklung mit Python und Qt6 – einzelne Prüfschritte im Code umgesetzt

Folgende Prüfschritte wurden im Code umgesetzt.

Für alle die lieber ein Video schauen, jetzt gibt es den Inhalt des Blogartikels auch als Video:

Screenreadertauglichkeit

Ein Screenreader ist eine Vorlesefunktion die blinden Menschen vorliest alles was auf dem Bildschirm bzw. Display zu sehen ist. Screenreader werden von blinden Menschen und von Menschen mit einer starken Sehbehinderung genutzt. Eine ausführliche Erklärung was ein Screenreader ist finden Sie in diesem Blogartikel: Screenreader leicht und verständlich erklärt .

Die Screenreadertauglichkeit wird explizit in der EN 301 549 nicht erwähnt, Sie ist aber wichtig, damit blinde Menschen eine Python-Qt-Anwendung bedienen können. Die Qt Bedienoberfläche muss texte enthalten die beschreiben, was auf der Oberfläche zu sehen ist. Diese Texte werden dann von einem Screenreader vorgelesen. Den Eingabefeldern und dem Button werden solche Texte hinterlegt mit setAccessibleDescription.

Codebeispiel:

self.font_size_button = MyPushButton('Schriftgröße ändern')
self.font_size_button.setAccessibleName("Schriftgröße ändern")  # Setze den zugänglichen Namen
  self.font_size_button.setAccessibleDescription(
            "Schriftgröße in der ganzen Anwendung ändern ")  # Setze die zugängliche Beschreibung

Die Screenreader lesen den Text vor der mit setAccessibleDescription gesetzt wurde.

Tastaturbedienbarkeit

Für eine barrierefreie Bedienung von Python-Qt-Anwendungen durch blinde und sehbehinderte Menschen ist es wichtig, dass alle Bedienelemente mithilfe der Tastatur erreichbar sind. Dies ist eine Anforderung gemäß Prüfschritt 9.2.1.1 „Ohne Maus nutzbar“ der EN 301 549. Um sicherzustellen, dass Benutzer die Bedienelemente mit der Tabulatortaste erreichen können, müssen keine zusätzlichen Programmierungen vorgenommen werden. Eine weitere Verbesserung der Tastaturbedienbarkeit kann durch die Nutzung von Tastenkombinationen für Eingabefelder erreicht werden. Hierzu werden die Labels mit den entsprechenden Eingabefeldern verknüpft. Dies geschieht wie folgt:

Codebeispiel:

label = QLabel(prop)
line_edit = MyLineEdit()
label.setBuddy(line_edit)  # Verknüpfung von Label und Eingabefeld

Um ein Label per Tastenkürzel erreichbar zu machen, muss dem Anfangsbuchstaben des Labels ein ‚&‘ vorangestellt werden.

Codebeispiel:

properties = ['&Vorname', '&Nachname', '&Straße', '&PLZ', '&Ort', '&Telefon', '&E-Mail']

Nach Drücken der Alt-Taste können die Labels mithilfe der entsprechenden Tastenkürzel angewählt werden. Durch die Verknüpfung mit den Eingabefeldern erhält das zugehörige Eingabefeld automatisch den Fokus werden. Damit die Buttons per Taste Enter ausführbar sind, muss setDefault(True) gesetzt werden.

Codebeispiel:

self.font_size_button.setDefault(True)

Aktuelle Position des Fokus deutlich

EN 301 549 Prüfschritt 9.2.4.7 Aktuelle Position des Fokus deutlich. Für Menschen mit einer Sehbehinderung ist es wichtig, dass sehr gut sichtbar ist welches Bedienelement der Eingabefokus hat. Dies kann erreicht werden in dem das aktive Bedienelement eine Gelbe Hintergrundfarbe bekommt.

Codebeispiel:

class MyLineEdit(QLineEdit):
    def __init__(self, parent=None):
        super().__init__(parent)

    def focusInEvent(self, event):
        self.setStyleSheet("QLineEdit { background-color: yellow; height: 3em; }")
        super().focusInEvent(event)

Kontraste von Texten ausreichend

EN 301 549 Prüfschritt 9.1.4.3 Kontraste von Texten ausreichend. Für Menschen mit einer Farbfehlsichtigkeit ist es wichtig, dass genug Farbkontrast zwischen Schriftfarbe und Hintergrundfarbe ist. Dies kann mit der Kostenlosen Software Colour Contrast Analyzer (CCA) Link: Colour Contrast Analyzer (CCA) überprüft werden. Hier ein Video von mir wie der Colour Contrast Analyzer eingesetzt werden kann: In der Python Qt-Anwendung musste keine Farbanpassung gemacht werden. Die Standardfarben sind barrierefrei.

Mindestgröße für Bedienelemente

Dieser Prüfschritt fehlt in der EN 301 549, dass bedeutet, es werden Menschen ausgegrenzt. WCAG 2.2 In der Richtlinie EN 301 549 fehlt dieser Prüfschritt, wodurch bestimmte Menschen ausgeschlossen werden. Hingegen ist dieser Prüfschritt in der WCAG 2.2 Success Criterion 2.5.8 Target Size (Minimum) enthalten und auch in den Google-Richtlinien „Apps barrierefrei gestalten“ unter dem Prüfschritt „Große, einfache Steuerelemente verwenden“ zu finden. Besonders für Menschen mit eingeschränkter Handfunktion, beispielsweise nach einem Schlaganfall, ist es wichtig, dass Schaltflächen eine Mindestgröße haben. Die WCAG empfehlen eine Größe von 24×24 Pixeln, während Google eine Mindesthöhe von etwa 3,5 REM (Fontgröße) empfiehlt. Diese Richtlinien setze ich bei der Entwicklung meiner barrierefreien Progressive Web Apps um, und sie haben sich in der Praxis bewährt. In dieser Python-Anwendung haben die Bedienelemente eine Höhe von 3em was ausreichend ist.

Codebeispiel:

class MyLineEdit(QLineEdit):
self.font_size_button.setStyleSheet("QPushButton { height: 3em; }")

Text auf 200% vergrößerbar + Benutzerdefinierte Einstellungen

Hier geht es um 2 Prüfschritte der EN 301 549. Prüfschritt 9.1.4.4 Text auf 200% vergrößerbar + Prüfschritt 11.7 Benutzerdefinierte Einstellungen Menschen mit einer Sehbehinderung passen im Betriebssystem die Schriftgröße an. Beispiel Windows 11: Einstellungen, Barrierefreiheit, Textgröße Die Pogrammiersprache Python erlaubt es nicht auf das Betriebssystem zu zugreifen. Deswegen muss eine Python Qt-Anwendung dafür sorgen, dass der Anwender die Schriftgröße anpassen kann. Dafür sorgt der Button Schriftgröße ändern und die Funktion def change_font_size(self).

Codebeispiel:

def change_font_size(self):
        # Dialog zum Ändern der Schriftgröße anzeigen
        new_font_size, ok = QInputDialog.getInt(self, 'Schriftgröße ändern', 'Neue Schriftgröße:', self.font_size)
        if ok:
            self.font_size = new_font_size
            # Schriftgröße aller relevanten Widgets anpassen
            for label in self.findChildren(QLabel):
                label.setFont(QFont('Arial', self.font_size))
            for line_edit in self.findChildren(QLineEdit):
                line_edit.setFont(QFont('Arial', self.font_size))
            for button in self.findChildren(QPushButton):
                button.setFont(QFont('Arial', self.font_size))

Der ganze Python-Code

Hier kommt der ganze Python-Code:

import sys
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QApplication, QWidget, QLabel, QLineEdit, QPushButton, QFormLayout, QVBoxLayout, \
    QInputDialog
from PyQt6.QtGui import QFont
from PyQt6.QtWidgets import QMessageBox


class MyForm(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('Daten einer Person eingeben')
        self.font_size = 12  # Standard-Schriftgröße
        self.init_ui()

    def init_ui(self):
        layout = QVBoxLayout()
        self.setLayout(layout)

        # Schaltfläche zum Ändern der Schriftgröße hinzufügen
        self.font_size_button = MyPushButton('Schriftgröße ändern')
        self.font_size_button.setAccessibleName("Schriftgröße ändern")  # Setze den zugänglichen Namen
        self.font_size_button.setAccessibleDescription(
            "Schriftgröße in der ganzen Anwendung ändern ")  # Setze die zugängliche Beschreibung
        self.font_size_button.clicked.connect(self.change_font_size)
        self.font_size_button.setStyleSheet("QPushButton { height: 3em; }")
        self.font_size_button.setDefault(True)
        layout.addWidget(self.font_size_button)

        form_layout = QFormLayout()
        layout.addLayout(form_layout)

        # Labels und Eingabefelder hinzufügen
        properties = ['&Vorname', '&Nachname', '&Straße', '&PLZ', '&Ort', '&Telefon', '&E-Mail']
        self.labels = []
        self.line_edits = []
        field_descriptions = {
            '&Vorname': 'Geben Sie den Vorname ein',
            '&Nachname': 'Geben Sie den Nachname ein',
            '&Straße': 'Geben Sie die Straße ein',
            '&PLZ': 'Geben Sie die Postleitzahl ein',
            '&Ort': 'Geben Sie den Ort ein',
            '&Telefon': 'Geben Sie die Telefonnummer ein',
            '&E-Mail': 'Geben Sie die E-Mail-Adresse ein'
        }
        for prop in properties:
            label = QLabel(prop)
            line_edit = MyLineEdit()
            line_edit.setAccessibleName(prop.replace('&', '') + " Eingabefeld")  # Setze den zugänglichen Namen
            line_edit.setAccessibleDescription(field_descriptions[prop])  # Setze die zugängliche Beschreibung
            line_edit.setStyleSheet("QLineEdit { height: 3em; }")
            form_layout.addRow(label, line_edit)
            self.labels.append(label)
            self.line_edits.append(line_edit)
            label.setBuddy(line_edit)  # Verknüpfung von Label und Eingabefeld

        # Button Abschicken
        submit_button = MyPushButton('Abschicken')
        submit_button.setAccessibleName("Submit-Button")  # Setze den zugänglichen Namen
        submit_button.setAccessibleDescription(
            "Klicken Sie hier, um das Formular zu senden")  # Setze die zugängliche Beschreibung
        submit_button.setStyleSheet("QPushButton { height: 3em; }")
        submit_button.setDefault(True)
        submit_button.clicked.connect(self.submit_form)
        layout.addWidget(submit_button)

        # Button Programm beenden
        submit_button = MyPushButton('Beenden')
        submit_button.setAccessibleName("Fenster schließen")  # Setze den zugänglichen Namen
        submit_button.setAccessibleDescription(
            "Programm beenden")  # Setze die zugängliche Beschreibung
        submit_button.setStyleSheet("QPushButton { height: 3em; }")
        submit_button.setDefault(True)
        submit_button.clicked.connect(self.close_application)
        layout.addWidget(submit_button)


    def submit_form(self):
        # Meldung anzeigen
        QMessageBox.information(self, "Formular abgeschickt", "Formular wurde abgeschickt!")

    def close_application(self):
        QApplication.quit()

    def change_font_size(self):
        # Dialog zum Ändern der Schriftgröße anzeigen
        new_font_size, ok = QInputDialog.getInt(self, 'Schriftgröße ändern', 'Neue Schriftgröße:', self.font_size)
        if ok:
            self.font_size = new_font_size
            # Schriftgröße aller relevanten Widgets anpassen
            for label in self.findChildren(QLabel):
                label.setFont(QFont('Arial', self.font_size))
            for line_edit in self.findChildren(QLineEdit):
                line_edit.setFont(QFont('Arial', self.font_size))
            for button in self.findChildren(QPushButton):
                button.setFont(QFont('Arial', self.font_size))


class MyLineEdit(QLineEdit):
    def __init__(self, parent=None):
        super().__init__(parent)

    def focusInEvent(self, event):
        self.setStyleSheet("QLineEdit { background-color: yellow; height: 3em; }")
        super().focusInEvent(event)

    def focusOutEvent(self, event):
        self.setStyleSheet("QLineEdit { height: 3em; }")  # Setze die Standard-Stylesheet zurück
        super().focusOutEvent(event)


class MyPushButton(QPushButton):
    def __init__(self, text, parent=None):
        super().__init__(text, parent)

    def focusInEvent(self, event):
        self.setStyleSheet("QPushButton { background-color: yellow; height: 3em; }")
        super().focusInEvent(event)

    def focusOutEvent(self, event):
        self.setStyleSheet("QPushButton { height: 3em; }")  # Setze die Standard-Stylesheet zurück
        super().focusOutEvent(event)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    form = MyForm()
    form.showMaximized()
    sys.exit(app.exec())

Schlussbemerkung

Mit der Programmiersprache Python und dem Framework Qt ist es möglich, eine barrierefreie Software zu entwickeln nach der EN 301 549 und der WCAG 2.2 .

Wenn Sie Fragen zu obige Themen haben, schreiben Sie mir eine Mail an info@marlem-software.de oder rufen Sie mich an unter 07072/1278463 .

Zum Weiterlesen

Autor: Markus Lemcke

Ich bin Markus Lemcke, Softwareentwickler, Webentwickler, Appentwickler, Berater und Dozent für barrierefreies Webdesign, barrierefreie Softwareentwicklung mit Java, C# und Python, Barrierefreiheit bei den Betriebssystemen Windows, Android, IOS, Ubuntu und MacOS.