In order to make a resizable 3d program i have created a scene3d in a layout and set the required properties. The scene resizing works properly while i change the height of windows but not in case of changing width.
I checked two examples of QTquick 3D and find out there's the same problem there.
To solve that i tried resizing windows by dynamic change scene scale in transform matrix4*4, and got this error:
after i ignore this, the program works correctly and resizes scene
AirplaneScene.qml:
Transform {
id: toyplaneTransform
matrix: {
var m = Qt.matrix4x4();
m.translate(Qt.vector3d(-30, -15, -30));
m.rotate(angle, Qt.vector3d(0, 1, 0));
m.rotate(rollAngle, Qt.vector3d(1, 0, 0));
m.rotate(pitchAngle, Qt.vector3d(0, 0,1));
m.scale(1.0 /scaleFactor );
return m;
}
main.qml:
Item{
id:sceneItem
Layout.preferredHeight: 700
Layout.preferredWidth: 1200
Layout.fillWidth: true
Layout.fillHeight: true
AirplaneScene{
id:airplane
scaleFactor: Math.round(mainLayout.width/sceneItem.width * 10) / 10
}
}
(when manually set the scalafactor this error not displaying)
I solved this problem by initialization scalefaktor with 3d scene to mainLayout ratio in AirplaneScene qml, and after loading page i changed scalefaktor dynamically
main.qml
property bool completeLoad: false
Component.onCompleted: {
completeLoad = true
}
onWidthChanged: {
if(completeLoad)
plane.scaleFactor= Math.round(mainLayout.width/sceneItem.width * 10) / 10
}
initialization scalefaktor in AirplaneScene.qml:
property real scaleFactor:1.3
Related
I have a Qt/QML program that runs on Ubuntu and on a Raspberry Pi 3B+. The program runs fine on both platforms however the Pi has a high DPI screen so I set a QT_SCALE_FACTOR to 1.3 on that device to make controls appear the right size. It works perfectly except for one thing: indicators on ComboBox and SpinBox controls are drawn the same size as if no QT_SCALE_FACTOR was set, and the rest of the rectangle they would fill if the QT_SCALE_FACTOR was applied is filled with random pixels. Setting a QT_SCALE_FACTOR on Ubuntu works without any issues.
I tried replacing the indicators with a custom one but I get the same result.
Leaving QT_SCALE_FACTOR unset produces correctly rendered indicators.
This is with Qt 5.13.2 and QtQuick.Controls 2.5 on Linux pi3 4.19.75-v7+ #1270 SMP Tue Sep 24 18:45:11 BST 2019 armv7l GNU/Linux
The pictures below illustrate the behavior with QT_SCALE_FACTOR=2:
This is the code for the custom indicator in the first picture:
ComboBox {
id: cb
...
width: 200
...
indicator: Canvas {
id: canvas
x: cb.width - width - cb.rightPadding
y: cb.topPadding + (cb.availableHeight - height) / 2
width: 12*2
height: 8*2
contextType: "2d"
Connections {
target: cb
function onPressedChanged() { canvas.requestPaint(); }
}
onPaint: {
var context = getContext("2d");
context.reset();
context.beginPath();
context.moveTo(0, 0);
context.lineTo(width, 0);
context.lineTo(width / 2, height);
context.closePath();
context.fillStyle = cb.pressed ? "#17a81a" : "#21be2b";
context.fill();
}
}
This question already has answers here:
How can I avoid creating a property binding on initialization in QML?
(5 answers)
Closed 4 years ago.
How to disable a the resizeability of QML objects? The height and width property of the object that I created are based on a scalable object, but i would not like for the object to be resized when the parent object is resized. How do I achieve this?
Window {
id: window
visible: true
title: qsTr("Stack")
Component.onCompleted: {
window.showMaximized()
}
Rectangle {
width:parent.width/2
height:parent.height/2
}
}
With the code above the rectangle will be created with 1/2 the size of the parent, and I would it to stay that way. When I resize the window the rectangle resizes too, I would like for it to be fixed after it is created. How do I achieve this? Thank you.
Remove your property bindings.
Window {
id: window
visible: true
title: qsTr("Stack")
Component.onCompleted: {
window.showMaximized()
rect.width = parent.width / 2; // use these
rect.height = parent.height / 2;
}
Rectangle {
id: rect
// width: parent.width/2 // no property bindings
// height: parent.height/2
}
}
By using property bindings on rect.width and rect.height, you're making them subject to dynamic change. You don't want that. Instead, you may call static assignments from Javascript.
If you place the JS code in Component.onCompleted, it will only run once (not updating every time the window resizes). These assignments won't create property bindings, fixing rect.width and rect.height.
I have a strange issue in QML when trying to draw relatively simple graphics.
I'm using PyQt 5 with QT 5.11 and Ubuntu 18.04.
Since the graphics part I'm writing is mostly stationnary (changes about each 1 secs), I found out canvas would be a convenient way to draw graphics without using QPainter. But it's been noting but a nightmare with fonts.
For example, when drawing this simple QML component:
import QtQuick 2.11
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.11
import QtGraphicalEffects 1.0
Rectangle {
id: cont_rect
Button {
text: "Repaint"
onClicked: {
cv.clearcv()
cv.requestPaint()
}
}
property string cvfont: "13px Ubuntu"
height: 80
width: 300
color: "#132931"
Canvas {
anchors.fill: parent
antialiasing: true
contextType: '2d'
id: cv
width: cont_rect.width
height: cont_rect.height
function clearcv() {
var ctx = cv.context
ctx.clearRect(0, 0, width, height)
ctx.fillStyle = "black"
}
function drawStateLine() {
var ctx = (cv.context == null) ? getContext("2d", {alpha: false}) : cv.context
var x = width/2, y = height - 10
var txt_angle = -45 * 2*Math.PI / 360
ctx.save()
ctx.translate(x,y)
ctx.rotate(txt_angle)
ctx.fillStyle = "royalblue"
ctx.textAlign = "left"
ctx.font = cvfont
ctx.textBaseline = "middle"
ctx.globalAlpha = 1
ctx.fillText("Detected", 0, 0)
ctx.restore()
}
onPaint: {
drawStateLine();
}
}
}
I end up with extremely weird graphics behavior.
The FIRST time my component is rendered, I have good looking text:
Then, when I click my specially crafted button (for the sake of isolating the problem down to a simple component), I have:
Basically, whenever I am trying to repaint my damn canvas, first clearing it (I also tried ctx.reset(), ctx.fillRect with my background color, etc.), I end up with font rendering that is much less readable and that bothers me.
Is there anyone here who has an idea on how to avoid this?
I don't know if it's useful, but I use a 27in display with 1080p resolution.
Thanks!
Hope this makes some sense as a question. In my app, I have a DragArea defined which I use to start dragging things over top of various Rectangles that each contain a DropArea. Everything is working fine in my code except for a cosmetic effect that I would like to change.
In QML, when you start dragging from a DragArea and eventually drop, the animation effect is such that the thing you're dragging animates (while fading out) back to the spot from which you started dragging. This happens even when you drop over a DropArea that successfully captures the drop.
What I would like to do is have the drop effect animate towards the DropArea that received the drop - so that it appears I am dragging-and-dropping things into the Rectangle. Is there any way to do this?
I'm guessing that this in some way involves the .source and .target properties of these areas, but no luck so far in having any effect on where the drop animation goes.
By default, QML will give you no cosmetic behavior for drag and drop whatsoever. The drag target will begin at the drag start location, and will end wherever it is dropped, regardless of whether the drag is accepted or not.
Thus I assume the behavior you describe is implemented in your user code, which you have not disclosed. Regardless, what you want to do is quite easy, it involves tracking the position the drag originates at and it ends at, so you can use the two coordinates to animate the position.
In the following example the red rectangle can be dragged, and if dropped outside of a drop area it will animate from its current to its initial position, whereas if dropped in the yellow rectangle, it will animate from its initial to its drop position.
Window {
width: 600
height: 600
visible: true
Rectangle {
width: 200
height: 200
color: "yellow"
DropArea {
anchors.fill: parent
onEntered: drag.source.accepted = true
onExited: drag.source.accepted = false
}
}
Rectangle {
id: rect
width: 50
height: 50
color: "red"
x: parent.width * 0.5
y: parent.height * 0.5
Drag.active: mouseArea.drag.active
property point begin
property point end
property bool accepted : false
MouseArea {
id: mouseArea
anchors.fill: parent
drag.target: parent
onPressed: rect.begin = Qt.point(rect.x, rect.y)
onReleased: {
rect.end = Qt.point(rect.x, rect.y)
aX.from = rect.accepted ? rect.begin.x : rect.end.x
aX.to = rect.accepted ? rect.end.x : rect.begin.x
aY.from = rect.accepted ? rect.begin.y : rect.end.y
aY.to = rect.accepted ? rect.end.y : rect.begin.y
anim.start()
}
ParallelAnimation {
id: anim
NumberAnimation { id: aX; target: rect; property: "x"; duration: 200 }
NumberAnimation { id: aY; target: rect; property: "y"; duration: 200 }
}
}
}
}
I'm designing the Spinner control (or You can Scollable list of items). Its working fine as far as the functionality is concerned
The main issue is the i want to create a circular motion feel in scrolling the items. So to give that effect in the scrolling list we decided to have preceding & trailing item size comparatively small than current item
I'm really struggling to get the different size of the items. Can any one suggest me how to proceed with the same.
Below is my code snippet
ContentModel.qml
import QtQuick 1.1
Rectangle {
property alias model: view.model
property alias delegate: view.delegate
property real itemHeight: height/5
clip: true
PathView {
id: view
anchors.fill: parent
//number of items visible on the path at any one time.
pathItemCount: height/itemHeight
// Ensuring the selected componenet to be at the center
preferredHighlightBegin: 0.5
preferredHighlightEnd: 0.5
// select maximum distance from the path that initiate mouse dragging
dragMargin: view.width
//Declare the path of list
path: Path {
startX: view.width/2; startY: -itemHeight/2
PathLine { x: view.width/2; y: view.pathItemCount*itemHeight + itemHeight/.8}
}
}
}
The main.qml snippet
main.qml
.......
ContentModel{
id: ContentModel_spinner
width: ContentModel_scroll.width; height: ContentModel_scroll.height
focus: true
model: 20
delegate: Text { font.pixelSize: index === ContentModel_spinner.currentIndex ? sec_spinner.height/4 : ContentModel_spinner.height/4.5; text: formatindex(index); height: ContentModel_scroll.height }
}
Check the tutorial here. They have given examples with different shapes of path views.