I'm encountering a strange behavior with Text in QML. Which I admit is probably my fault, but I can not figure out what's wrong. I am creating a swipe menu like the ones used on the Gmail/Inbox app for android. As it was answered here I found that the best way to have the swipe menu with buttons inside was to create my own buttons, so I have the following code:
MenuButton:
Item {
id: root
property string text: ""
signal clicked()
width: 100
height: 62
Rectangle {
anchors.fill: parent
}
Text {
anchors.centerIn: parent
text: parent.text
}
MouseArea {
anchors.fill: parent
onClicked: {
parent.clicked();
}
}
}
My SliderMenu is as follows:
Item {
id: root
function showMenu(startX, duration) {
//Start animation to show menu.
}
function hideMenu(startX, duration) {
//Start animation to hide menu.
}
clip: true
visible: false
Item {
id: menu
//shadow adds 1 pixel
property int maxX: -1
property int minX: -width - 1
//Arbitrary number for what is considered fast
property int fastSwipe: 200
y: -1
width: 250
height: parent.height + 1
visible: false
Rectangle {
id: rectMenu
anchors.fill: parent
color: "#ececec"
visible: false
}
DropShadow {
id: menuShadow
anchors.fill: rectMenu
horizontalOffset: 1
verticalOffset: 0
radius: 4
samples: radius * 2
spread: 0
color: "#80000000"
source: rectMenu
transparentBorder: true
}
MenuButton {
x: 10
y: 20
text: "Text"
onClicked: {
console.log("I'm here!");
}
}
SwipeArea {
//Swipe area code
}
NumberAnimation {
//Code of the sliding in animation
}
NumberAnimation {
//Code for the sliding out animation
}
}
}
The slider is opened by clicking on the TopMenu's Button:
Rectangle {
id: root
height: 50
color: "#4285f4"
border.width: 0
border.color: "#00000000"
property SliderMenu slider
ToolButton {
id: slideButton
x: 5
y: 7
width: 36
height: 36
iconSource: "../../resources/MainMenu/slide_menu_icon.png"
onClicked: {
slider.showMenu();
}
}
}
Which is like this on main:
Item {
anchors.fill: parent
z: 1
TopMenu {
x: 0
y: 0
width: parent.width
height: 50
slider: sliderMenu
}
SliderMenu {
id: sliderMenu
x: 0
y: 0
anchors.fill: parent
}
}
When I press the TopMenu's Button to slide the menu into view, 90% of the time (not always) the app will crash. If I remove the Text from the MenuButton it won't crash anymore. Also, I've tried adding a Text anywhere on the SlideMenu instead of the MenuButton and it gives the same result.
I've also tried to make the Menu always visible (so I won't have to press the Button for it to appear) and the app does not crash anymore but 90% of the time the Text is not there!
It only seems to crash if it is initially hidden and, if it doesn't crash at first, it won't anymore, even if I hide the menu and open again.
The crash gives a segmentation fault on Debug.
Anyone has any idea of what this might be?
Thank you for your time.
EDIT: I was running this on windows because it is faster to test and I want it to also run on windows. I've just tested inside an android and it doesn't seem to be crashing. But I get this error on my console every time I open or close the menu:
Drawable.qml:70 ((null)): file:///data/data/org.qtproject.example.OSC_Client/qt-reserved-files/qml/QtQuick/Controls/Styles/Android/drawables/Drawable.qml:70: TypeError:
Cannot read property 'padding' of undefined
W/libOSC-Client.so(25977): file:///data/data/org.qtproject.example.OSC_Client/qt-reserved-files/qml/QtQuick/Controls/Styles/Android/drawables/AnimationDrawable.qml:53 ((null)): file:///data/data/org.qtproject.example.OSC_Client/qt-reserved-files/qml/QtQuick/Controls/Styles/Android/drawables/AnimationDrawable.qml:53:28:
Unable to assign [undefined] to bool
EDIT2: I've just managed to replicate this bug in a simpler manner. This seems to be related to the DropShadow on the rectangle. The simpler code is bellow. When I run it, 90% of the time the text does not appear. Tested on both MinGW and MSVC2012 on windows.
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtGraphicalEffects 1.0
ApplicationWindow {
title: qsTr("Hello World")
width: 640
height: 480
visible: true
Button {
x: 0
y: 350
text: "Show Rectangle"
onClicked: rect.visible = true;
}
Item {
id: rect
x: -1
y: -1
width: 250
height: 300
visible: false
Rectangle {
id: rectMenu
anchors.fill: parent
color: "#ececec"
visible: false
}
DropShadow {
id: menuShadow
anchors.fill: rectMenu
horizontalOffset: 1
verticalOffset: 0
radius: 4
samples: radius * 2
spread: 0
color: "#80000000"
source: rectMenu
transparentBorder: true
}
Text {
anchors.centerIn: parent
text: "Text"
}
}
}
If I remove the DropShadow it'll show the text normally.
qt.qpa.gl Log:
qt.qpa.gl: createPlatformOpenGLContext QSurfaceFormat(version 2.0, options QFlags(), depthBufferSize 24, redBufferSize -1, greenBufferSize -1, blueBufferSize -1, alphaBufferSize -1, stencilBufferSize 8, samples -1, swapBehavior 2, swapInterval 1, profile 0)
qt.qpa.gl: Qt: Using WGL and OpenGL from "opengl32.dll"
qt.qpa.gl: create OpenGL: "Intel","Intel(R) HD Graphics 3000" default ContextFormat: v3.1 profile: 0 options: QFlags(0x4),SampleBuffers, Extension-API present
Extensions: 116
qt.qpa.gl: "choosePixelFormat Attributes: 0x2003 , 0x2027 , 0x2010 , 0x1 , 0x2001 , 0x1 , 0x2014 , 0x18 , 0x2011 , 0x1 , 0x2022 , 0x18 , 0x2013 , 0x202b , 0x201b , 0x8 , 0x2023 , 0x8 , 0x2041 , 0x0 ,
obtained px # 4 of 1
PIXELFORMATDESCRIPTOR dwFlags=0x8225 PFD_DRAW_TO_WINDOW PFD_SUPPORT_OPENGL PFD_SUPPORT_COMPOSITION PFD_DOUBLEBUFFER iPixelType=0 cColorBits=32 cRedBits=8 cRedShift=16 cGreenBits=8 cGreenShift=8 cBlueBits=8 cBlueShift=0 cDepthBits=24 cStencilBits=8 iLayerType=0 cAlphaBits=8 cAlphaShift=24 cAccumBits=64 cAccumRedBits=16 cAccumGreenBits=16 cAccumBlueBits=16 cAccumAlphaBits=16"
qt.qpa.gl: createContext Creating context version 2 . 0 3 attributes
qt.qpa.gl: QWindowsGLContext 0x281246a0 ARB requested: QSurfaceFormat(version 2.0, options QFlags(), depthBufferSize 24, redBufferSize -1, greenBufferSize -1, blueBufferSize -1, alphaBufferSize -1, stencilBufferSize 8, samples -1, swapBehavior 2, swapInterval 1, profile 0)
obtained # 4 ARB QSurfaceFormat(version 3.1, options QFlags(0x4), depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8, alphaBufferSize 8, stencilBufferSize 8, samples 0, swapBehavior 2, swapInterval 1, profile 0)
PIXELFORMATDESCRIPTOR dwFlags=0x8225 PFD_DRAW_TO_WINDOW PFD_SUPPORT_OPENGL PFD_SUPPORT_COMPOSITION PFD_DOUBLEBUFFER iPixelType=0 cColorBits=32 cRedBits=8 cRedShift=16 cGreenBits=8 cGreenShift=8 cBlueBits=8 cBlueShift=0 cDepthBits=24 cStencilBits=8 iLayerType=0 cAlphaBits=8 cAlphaShift=24 cAccumBits=64 cAccumRedBits=16 cAccumGreenBits=16 cAccumBlueBits=16 cAccumAlphaBits=16 swap interval: 1
default: ContextFormat: v3.1 profile: 0 options: QFlags(0x4)
HGLRC=0x20000
Related
I want to change the default shape of text edit Cursor and it should be like below
TextArea {
id: txtTalk
anchors.fill: parent
leftPadding: 9
rightPadding: 9
wrapMode: TextArea.Wrap
color: Material.color(Material.Red,Material.Shade900)
background: Rectangle{
radius: 3
color: Material.color(Material.Red,Material.Shade50)
border.width: 1
border.color: Material.color(Material.Red,Material.Shade300)
}
}
The following code should do what you want. You could also add blinking animations, have look at this CursorDelegate example.
The only issue with SVG in QML is the poor aliasing. What you could do is compose the "pin" of two Rectangles one with rounded corners (radius property) and the other one rotated. Or you could have a look at how to get rid of aliasing with SVGs in QML.
Instead of using PathSVG you could also compose your pin icon of PathLine and PathArc.
Keep in mind that I didn't pay attention on dynamic placement of the pin and its scaling, I tweaked the values until it looked alright. Another thing would be to scale the pin in relation to your font size.
import QtQuick 2.0
import QtQuick.Controls 2.15
import QtQuick.Shapes 1.15
Item {
width: 640
height: 480
TextArea {
anchors.centerIn: parent
wrapMode: TextArea.Wrap
color: "gray"
font.pixelSize: 24
background: Rectangle{
implicitWidth: 300
implicitHeight: 200
radius: 3
color: "white"
border.width: 1
border.color: "black"
}
placeholderText: qsTr("Enter description")
cursorDelegate: Item {
width: 1
Rectangle {
id: rectangle
color: "black"
y: 1
width: 2
height: parent.height - 2
Shape {
x: -8
y: rectangle.height + 2
ShapePath {
fillColor: "red"
strokeWidth: -1
scale: Qt.size(0.2, 0.2)
PathSvg { path: "M 45,90 C 25.463,90 9.625,74.162 9.625,54.625 c 0,-8.722 3.171,-16.693 8.404,-22.861 L 45,0 71.97,31.765 c 5.233,6.167 8.404,14.139 8.404,22.861 C 80.375,74.162 64.537,90 45,90 Z" }
}
}
}
}
}
}
The following standard QML code does not work. Instead of the 3 small bar menu icon (unicode u2630), I get a rectangle with a cross inside: it does not find the character. However it finds the u25C0 left arrow (back triangle button) when required.
This is only a cosmetic glitch, as it works perfectly.
Has this anything related to the font, or with a mapping to an icon? How to solve this?
import QtQuick 2.15
import QtQuick.Controls 2.15
ApplicationWindow {
id: window
width: 640
height: 480
visible: true
title: qsTr("Stack")
header: ToolBar {
contentHeight: toolButton.implicitHeight
ToolButton {
id: toolButton
text: stackView.depth > 1 ? "\u25C0" : "\u2630"
font.pixelSize: Qt.application.font.pixelSize * 1.6
onClicked: {
if (stackView.depth > 1) {
stackView.pop()
} else {
drawer.open()
}
}
}
Label {
text: stackView.currentItem.title
anchors.centerIn: parent
}
}
(...)
For those who come here from search I will leave here the answer from a Qt.io forum
https://forum.qt.io/topic/123877/stackview-icon-on-android
Since the last update of the Gboard Qt seems to have issues with detecting it and push input fields above it accordingly.
Gboard version: 9.7.09.323382208-tv_release-armeabi-v7a
I have a minimal code example in which it can be easily reproduced:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
ApplicationWindow {
width: 1920
height: 1080
visibility: Window.Maximized
color: "#C0C0C0"
Item
{
width: 1920 * 0.7
height: 1080 * 0.8
Item {
width: parent.width
height: parent.height * 0.4
id: we
}
TextField
{
id: input1
width: parent.width
focus: true
anchors.top: we.bottom
onAccepted: input2.focus = true
Keys.onPressed:
{
switch (event.key) {
case Qt.Key_Tab:
case Qt.Key_Down:
event.accepted = true
input2.forceActiveFocus()
break
}
}
}
TextInput
{
id: input2
width: parent.width
anchors.top: input1.bottom
maximumLength: 40
Keys.onPressed:
{
switch (event.key) {
case Qt.Key_Tab:
case Qt.Key_Down:
event.accepted = true
break
case Qt.Key_Up:
event.accepted = true
input1.forceActiveFocus()
break
}
}
}
}
}
I tried to build with Qt versions: 5.12.9, 5.13.2, 5.14.2, 5.15.1 and all have the same issue. However an empty project from Android studio will push the input fields correctly, so the issue must be Qt related.
I also tried to set android:windowSoftInputMode="adjustPan" but it had no effect at all.
What I found is the Qt showSoftwareKeyboard method in QtActivityDelegate.java, I assume it's responsible for displaying the keyboard and adjusting the layouts, so I tried to play around with it a bit (setting some hard-coded values e.g. m_layout.setLayoutParams(m_editText, new QtLayout.LayoutParams(width, 680, 30, 500), false)), rebuild Qt with the changes, but with no success or visible changes, it does print out my custom logs so the changes did apply correctly.
Any ideas how to make it push the input fields?
In the code below, the row of buttons shows behing the Android lower bar of button (triangle, circle, square). When I rotate, everything is fine. When I rotate back, everything is fine too.
So it is only the first time that something goes wrong.
Any idea ?
import QtQuick 2.4
import QtQuick.Controls 2.15
import QtQuick.Window 2.15
Item {
property alias unit_add: unit_add
width: Screen.desktopAvailableWidth
height: Screen.desktopAvailableHeight
ListView {
(...)
}
Row {
id: buttons
width: parent.width
height: 43
visible: true
spacing: 16
anchors.bottom: parent.bottom
anchors.topMargin: 10
anchors.bottomMargin: 10
anchors.horizontalCenter: parent.horizontalCenter
Button {
id: unit_add
text: qsTr("Add")
}
Button {
id: unit_delete
text: qsTr("Delete")
}
Button {
id: unit_edit
text: qsTr("Edit")
}
}
}
I'm trying to make some sort of fotboll app for android. The problem i'm facing right now, is that I need to make a button in the corner of the screen, (4 different) which you move the game character with. But I've made 1 button now, for moving up, but it doesnt appear on the screen.
Main file:
import QtQuick 2.0
import QtQuick.Window 2.1
Item {
id:root
width:Screen.width
height:Screen.height-10
focus:true
Keys.onPressed: {
if(event.key===Qt.Key_Up)
{
event.accepted = true;
player.y=(player.y) - 40
}
if(event.Key === Qt.Key_Down){
event.accepted = true;
player.y = (player.y)+ 40
}
if (event.key === Qt.Key_Right)
{ event.accepted=true;
player.x=(player.x)+40
}
if (event.key === Qt.Key_Left)
{event.accepted = true;
player.x=(player.x) -40
}
}
Flickable {
width:Screen.width
height:Screen.height
contentHeight: Screen.height*2
contentWidth:Screen.width
interactive:true
boundsBehavior: Flickable.StopAtBounds
contentY: Math.min(contentHeight-height, Math.max(0, player.y-height/2))
contentX: Math.min(contentWidth-width, Math.max(0, player.x-width/2))
Image{
id: feild
anchors.fill:parent
source:"Namnlös.png"
sourceSize.height:Screen.height*2
sourceSize.width:Screen.width
}
Image {
id: player
source:"asd.png"
x:Screen.width/2
y:Screen.height/2
}
}
}
Button file:
import QtQuick 2.0
import QtQuick.Window 2.1
Rectangle {
id: simplebutton
color: "grey"
width: 100; height: 50
Text {
id: buttonLabel
anchors.centerIn: parent
text: "Up"
}
MouseArea {
id: buttonMouseArea
anchors.fill: parent
onClicked: console.log(buttonLabel.text + "clicked" )
}
}
Rectangle {
id: button
property color buttonColor: "lightblue"
property color onHoverColor: "gold"
property color borderColor: "white"
signal buttonClick()
onButtonClick: {
console.log(buttonLabel.text + " clicked" )
}
MouseArea {
onClicked: buttonClick()
hoverEnabled: true
onEntered: parent.border.color = onHoverColor
onExited: parent.border.color = borderColor
}
color: buttonMouseArea.pressed ? Qt.darker(buttonColor, 1.5) : buttonColor
}
Two things:
1) You need to add your button to your layout! Since there you don't add your button into your main file, it won't appear.
2) You need to split your Button file into two separate qml file, since you can only have one "root" item per file.