I am adding accessibility to QML application. While using Windows Narrator or NVDA program, they are not able to read elements of ComboBox. They read ComboBox fine but not content of it.
Cannot post my project to posting example file here.
QML:
import QtQuick 2.14
import QtQuick.Window 2.14
import QtQuick.Controls 2.14
Item {
visible: true
width: 640
height: 480
ComboBox{
model: ["option1","option2","option3"]
Accessible.name: "ComboBox"
Accessible.description: "ComboBox"
}
}
Main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickView>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQuickView view;
const QUrl url(QStringLiteral("qrc:/main.qml"));
view.setSource(url);
view.show();
return app.exec();
}
Qt Version: 5.15.2, any help is appreciated
So, after browsing QT Bugs found out that QML is not fully supported for accessibility and QT is aware of it since 2016. This ticket is really helpful
https://bugreports.qt.io/browse/QTBUG-68465 and from comments
Qt should actually be setting focus to the menu's first child menu item, since this is thew behavior VoiceOver expects. We currently don't do this.
So by forcing focus this can be fixed, i am able to fix it.
Check focus:true that is most important part.
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
Item {
visible: true
width: 640
height: 480
ComboBox{
id: selectMe
model: ["selectMe1","selectMe2","selectMe3"]
focus: true
Accessible.role: Accessible.ComboBox
contentItem:
Text {
id: ld2
text: selectMe.currentText
}
hoverEnabled: true
popup: Popup {
y: selectMe.height - layoutRowHeight
width: selectMe.width
implicitHeight: contentItem.implicitHeight
padding: 1
focus: true
contentItem: ListView {
spacing: 2
focus: true
Accessible.role: Accessible.List
clip: true
implicitHeight: contentHeight
model: selectMe.popup.visible ? selectMe.delegateModel : null
delegate: ItemDelegate {
id: selectMeDelegate
width: selectMe.width
focus: true
contentItem:
Text {
text: modelData
color: "black"
font.pointSize: 12
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft
focus: true
Accessible.name: "selectMe combobox"
Accessible.description: "selectMe"
}
background: Rectangle{
width: selectMe.width
height: selectMe.height
}
}
}
background: Rectangle {
color:"grey"
opacity: 0.5
radius: 10
}
}
}
}
Related
I'm working on a project that gets news with API. I can clearly get the news from api and load them to the listview.
I simplify the code for telling my problem clearly.
Here is a 2 questions...
1 - I need to slide this list from top to the bottom basic sliding animation with given time. (eg. y from 0 to en of list with 5secs). The important point is the item count of the list can be changeable.
2 - When the animation reachs to the end of the list, I need to see the first item after the last item. But it has to be like this; after the last item of list, the first item has to shown( like infinite list) while the sliding process going on.
Here are my codes;
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QDebug>
#include <QQmlContext>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QStringList news = { "news01",
"news02",
"news03",
"news04",
"news05",
"news06",
"news07",
"news08",
"news09",
"news10",
"news11",
"news12",
"news13",
"news14",
"news15",
"news16",
"news17",
"news18",
"news19",
};
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("listNews",news);
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.0
import QtGraphicalEffects 1.0
import QtQuick.Layouts 1.3
Window {
id:pencere
visible: true
width: 640
height: 480
title: qsTr("Hello World")
color: "black"
ListView{
id: newsListView
implicitWidth: parent.width
implicitHeight: parent.height
model:listNews
spacing: 5
delegate: Rectangle {
id: delegateBackground
color:"#505051"
radius: 10
width: parent.width
height: contentContainer.height + 20
Item {
id: contentContainer
width: parent.width - 20
height: column.height
anchors.centerIn: delegateBackground
RowLayout {
width: parent.width
Rectangle {
id: newsicon
width: 16
height: 16
color: "steelblue"
Layout.alignment: Qt.AlignTop
}
ColumnLayout {
id: column
Layout.fillWidth: true
spacing: 100
Text {
Layout.fillWidth: true
Layout.alignment: Qt.AlignBottom
id: messageText
text: modelData
wrapMode: TextEdit.WordWrap
verticalAlignment: index %2 == 0 ? Text.AlignBottom : Text.AlignTop
color: "white"
}
}
}
}
}
}
}
For the first question you could add something like the following to your ListView. This will trigger an animation if you press the arrow key up/down. It isn't perfect, but it explains how to use NumberAnimations. The key to move the ListView content is the property contentY. If you want to scroll all the way to the bottom of the news feed you could calculate the position by using contentHeight of the ListView and the Window height.
ListView {
id: newsListView
property bool scrollUp: false
property bool scrollDown: false
focus: true
Keys.onUpPressed: newsListView.scrollUp = true
Keys.onDownPressed: newsListView.scrollDown = true
NumberAnimation on contentY {
running: newsListView.scrollDown
from: 0
to: newsListView.contentHeight
duration: 1000
onFinished: newsListView.scrollDown = false
}
NumberAnimation on contentY {
running: newsListView.scrollUp
from: newsListView.contentHeight
to: 0
duration: 1000
onFinished: newsListView.scrollUp = false
}
...
}
For the first question as proposed by #iam_peter, you can try using NumberAnimation to animate scrolling. For second query, in my opinion you can try researching on PathView as it is much easier to get circular list behavior in PathView without cumbersome index calculations.
Also, please have a look at this topic ListView Scrolling.
I am using Qt 5.13 and in general Qt.Controls 2 however the calendar only exists in v1.0 or the labs version (which I can't get to work, so using V1).
My code is
import QtQuick 2.2
import QtQuick.Controls 1.4 as Old
import Tree 1.0
import "."
ApplicationWindow {
id: window
width: 800; height: 1000
title: "TreeView Example"
visible: true
Old.Calendar {
anchors.centerIn: parent
id: calendar
}
}
However when I do this, I don't see the day of the week, nor the month/year in the navivagation bar, although I can see where they should be:
I have tried to add a navigationBar delegate, but this then gets rid of the navigation arrows.
style: CalendarStyle {
navigationBar: Text {
text: "hello"
}
}
So, how do I have the nav arrows, show the month/year and show the days of week? The documentation seems to suggest I would get these out of the box...
Now... I thought I could add drop downs as a work around to choose month/year and place them in the nav bar... however when I do that I can actually see that the days of the week are there, just their text colour is white, so I feel I am missing a trick with regard to the navigation bar...?
Worth reading the comments in response to #Aleph0's post, but to get it working I had to copy the default styles and place them within my element. The final code (stripping out the bits that aren't specifically about the calendar then), looks like
import QtQuick.Controls 2.4
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.3
import QtQuick 2.2
import QtQuick.Controls 1.4 as Old
import QtQuick.Controls.Styles 1.4
import QtQuick.Controls.Private 1.0
ApplicationWindow {
id: window
width: 300; height: 300
title: "Calendar Example"
visible: true
ColumnLayout {
anchors.fill: parent
Old.Calendar {
id: calendar
style: CalendarStyle {
gridVisible: true
dayOfWeekDelegate: Rectangle {
color: gridVisible ? "#fcfcfc" : "transparent"
implicitHeight: Math.round(TextSingleton.implicitHeight * 2.25)
Label {
text: control.locale.dayName(styleData.dayOfWeek, control.dayOfWeekFormat)
anchors.centerIn: parent
}
}
navigationBar: Rectangle {
height: Math.round(TextSingleton.implicitHeight * 2.73)
color: "#f9f9f9"
Rectangle {
color: Qt.rgba(1,1,1,0.6)
height: 1
width: parent.width
}
Rectangle {
anchors.bottom: parent.bottom
height: 1
width: parent.width
color: "#ddd"
}
HoverButton {
id: previousMonth
width: parent.height
height: width
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
source: "./assets/leftanglearrow.png"
onClicked: control.showPreviousMonth()
}
Label {
id: dateText
text: styleData.title
elide: Text.ElideRight
horizontalAlignment: Text.AlignHCenter
font.pixelSize: TextSingleton.implicitHeight * 1.25
anchors.verticalCenter: parent.verticalCenter
anchors.left: previousMonth.right
anchors.leftMargin: 2
anchors.right: nextMonth.left
anchors.rightMargin: 2
}
HoverButton {
id: nextMonth
width: parent.height
height: width
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
source: "./assets/rightanglearrow.png"
onClicked: control.showNextMonth()
}
}
}
}
}
}
That results in
In an ideal world, there would be an alternative to a) using Private controls as that seems like I am using Qt internal modules, but thats an easy fix by using an Image with a mouse area, and if I didn't have to use any 1.x controls either, but there doesn't seem to be a 2.x way of graphically displaying dates etc. Anyway, hopefully this can be useful to someone - it's literally a copy paste job of the default styling so it can be simplified alot...
I'm also using Qt 5.13.0 and just tried you example. After removing some imports it was working with the following files:
main.qml
import QtQuick 2.2
import QtQuick.Controls 1.4 as Old
import QtQuick.Controls 2.12
ApplicationWindow {
id: window
width: 800; height: 1000
title: "TreeView Example"
visible: true
Old.Calendar {
anchors.centerIn: parent
id: calendar
}
}
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
QQmlContext* context = engine.rootContext();
engine.load(QUrl("./data/main.qml"));
return app.exec();
}
I'll obtain the following:
I suggest, that you will try my code and compare it with your application.
I had the same problem - days of week and title were almost invisible, because they were written with white color on light gray background. In my case the problem was in desktop color theme in Ubuntu Studio. After I changed it from Dark to Light the text appeared in black as expected. It seems Qt5 can't handle dark themes well or implementation in Ubuntu Studio (22.04) is buggy. The same was true for text in Button-s.
I have a form where i've done a custom field that only accepts the top, right and bottom arrows.
But to accept the tab navigation i'm using the following chain of functions:
nextItemInFocusChain().forceActiveFocus()
The problem is that this is working on windows but not on mac...
I've a formulary to illustrate the problem where next to that "code text field" i have a comboBox where i want, that when the user clicks on tab in the "code text field" to navigate to.
It seems that it only navigates to other textFields, and a spinBox, like i have on the example seems to have a textField as a contentItem.
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
main.qml
import QtQuick 2.9
import QtQuick.Controls 2.0
ApplicationWindow {
id: window
title: "Stack"
visible: true
height: 200
width: 400
Item {
id: page
anchors.fill: parent
width:parent.width
height: parent.height
Column{
width:parent.width
spacing:10
TextField {
id:textField
KeyNavigation.tab: spinBox1
implicitHeight: 30
font.bold: true
}
SpinBox {
id: spinBox1
width: 100
height: 30
editable: true
Component.onCompleted: contentItem.KeyNavigation.tab = userCodeField
}
PanelCodeField {
id: userCodeField
width: 100
height: 30
KeyNavigation.tab: comboBox
}
ComboBox {
id:comboBox
anchors.topMargin: 10
model: [ "Banana", "Apple", "Coconut" ]
KeyNavigation.tab: spinBox2
}
SpinBox {
id: spinBox2
width: 100
height: 30
editable: true
Component.onCompleted: contentItem.KeyNavigation.tab = textField
}
}
}
}
PanelCodeField.qml
import QtQuick 2.0
PanelTextField {
height: 479.9
visible: true
maximumLength: 5
font.pointSize: 12
property bool jumpOnTab: false
Keys.onPressed: {
var c
switch (event.key) {
case Qt.Key_Up:
c = String.fromCharCode(0x25B2)
break
case Qt.Key_Down:
c = String.fromCharCode(0x25BC)
break
case Qt.Key_Right:
c = String.fromCharCode(0x25B6)
break
case Qt.Key_Tab:
if(jumpOnTab)
nextItemInFocusChain().nextItemInFocusChain().forceActiveFocus()
else
nextItemInFocusChain().forceActiveFocus()
event.accepted = true
break
default:
event.accepted = true
break
}
if (!event.accepted) {
var s = text.concat(c)
text = s.substr(Math.max(0,s.length-maximumLength), maximumLength)
event.accepted = true
}
}
}
PanelTextField.qml
import QtQuick 2.0
import QtQuick.Controls 2.0
TextField {
property var linkedData
implicitHeight: 30
font.bold: true
implicitWidth:parent.width
}
Am i doing something wrong for the mac os x, or is there a workaround?
Open System Preferences > Keyboard > Shortcuts and select All Controls. By default macOS only allows tab navigation between "Text boxes and lists only".
I've included on my QT project the fontawesome font:
This one https://fontawesome.com/how-to-use/on-the-desktop/setup/getting-started
The problem is that it works well with windows system but not in MAC.
Below i'm going to show a sample app with all the code to illustrate the problem:
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QFile res2(":/resources/fonts/Font Awesome 5 Free-Solid-900.otf");
QFile res3(":/resources/fonts/Font Awesome 5 Free-Regular-400.otf");
QFile res4(":/resources/fonts/Font Awesome 5 Brands-Regular-400.otf");
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
main.qml
import QtQuick 2.7
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.3
import QtQuick.Window 2.3
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
FontLoader { id: fontAwesomeSolid; source: "fonts/Font Awesome 5 Free-Solid-900.otf" }
FontLoader { id: fontAwesomeRegular; source: "fonts/Font Awesome 5 Free-Regular-400.otf" }
FontLoader { id: fontAwesomeBrands; source: "fonts/Font Awesome 5 Brands-Regular-400.otf" }
Button {
id:buttonAbout
anchors.right: parent.right
anchors.rightMargin: 10
anchors.bottomMargin: 0
width:15
height: 15
text: "\uf129"
font.family: fontAwesomeRegular.name
contentItem: Text {
anchors.fill:buttonAbout
anchors.right:buttonAbout.right
anchors.bottomMargin: 3
text: buttonAbout.text
font: buttonAbout.font
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
background:
Rectangle{
width:15
height: 15
anchors.top:parent.top
anchors.right: parent.right
radius:10
border.width: 1
border.color:"gray"
}
onClicked: popup.open()
}
Popup {
id: popup
x: 100
y: 100
width: 200
height: 300
modal: true
focus: true
closePolicy: Popup.CloseOnEscape | Popup.close()
}
}
I've created a new .qrc file where i added the folder fonts of fontawesome
Font Awesome 5 Free-Solid-900.otf
Font Awesome 5 Free-Regular-400.otf
Font Awesome 5 Brands-Regular-400.otf
That screens that demonstrate what happens, in windows:
and in MAC:
This was done with QT 5.12
EDIT:
i provide the code for this app
https://drive.google.com/file/d/1ZSZBzg0fS9IUNpQ540M4cGlRQATV4NlU/view?usp=sharing
This way can anyone that uses MAC test this code please?
I've been searching how to make the background of my QtQuick 2.0 application transparent.
Most answers I've found use QtDeclarative which is ok for QtQuick 1.0 but not version 2.
Finally I found an answer that I will post but I would like to know if there is a better/simpler/smaller way to achieve this task.
Note*
I wanna make the Background of the window transparent.
Some people suggest to setOpacity but this makes all the qml elements transparent.
I found a solution in this post http://qt-project.org/forums/viewthread/18984/#106629 by billouparis. He uses the main application template that is being generated by QtCreator which is pretty convenient.
Note: I changed a little bit the original code to make it smaller.
#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
#include <QSurface>
#include <QSurfaceFormat>
#include <QDebug>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QtQuick2ApplicationViewer viewer;
// Make Background Transparent Start
viewer.setSurfaceType(QSurface::OpenGLSurface);
QSurfaceFormat format;
format.setAlphaBufferSize(8);
format.setRenderableType(QSurfaceFormat::OpenGL);
viewer.setFormat(format);
viewer.setColor(QColor(Qt::transparent));
viewer.setClearBeforeRendering(true);
// Make Background Transparent Stop
viewer.setMainQmlFile(QStringLiteral("qml/myProject/main.qml"));
viewer.showExpanded();
return app.exec();
}
Also make sure that the root qml element has an alpha color (Qt.rgba)
here a example to get a frameless, transparent window in pure qml
import QtQuick 2.2
import QtQuick.Window 2.0
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
ApplicationWindow {
id: backlight
flags: Qt.FramelessWindowHint
visible: true
title: qsTr("backlight")
width: 500
height: 50
x: (Screen.width - width) / 2
y: (Screen.height - height) / 2
color: "transparent"
property real slideValue
signal onSlide(real value)
Rectangle {
anchors.centerIn: parent
width: parent.width
height: 50
color: "transparent"
Rectangle {
anchors.fill: parent
radius: 25
opacity: 0.3
color: "gray"
}
Slider {
anchors.centerIn: parent
width: backlight.width - 16
height: backlight.height
value: backlight.slideValue
focus: true
onValueChanged: backlight.onSlide(value)
Keys.onSpacePressed: Qt.quit()
Keys.onEscapePressed: Qt.quit()
style: SliderStyle {
groove: Rectangle {
implicitHeight: 8
radius: 4
color: "gray"
}
handle: Rectangle {
anchors.centerIn: parent
color: control.pressed ? "white" : "lightgray"
border.color: "gray"
border.width: 2
width: 34
height: 34
radius: 17
}
}
}
}
}
Try this
import QtQuick 2.2
import QtQuick.Window 2.0
Window {
id: backlight
visible: true
title: qsTr("backlight")
width: 500
height: 50
x: (Screen.width - width) / 2
y: (Screen.height - height) / 2
color: "transparent"
}