I had created a video player in QML having zooming functionality. I want to add the Google Map like zooming functionality in it that is zoom from the center of the current visible frame. I can center the image using:
videoScrollControl1.flickableItem.contentX = (videoScrollControl1.flickableItem.contentWidth-imgVideo.width)/2
videoScrollControl1.flickableItem.contentY= (videoScrollControl1.flickableItem.contentHeight-imgVideo.height)/2
but the problem is that it always zoom to the center of the Image. I want to zoom from any point or from the center of current visible frame. my Code is as follows:
ScrollView {
id: videoScrollControl1
anchors.fill: parent
anchors.margins: 5
frameVisible: false
contentItem: Rectangle {
id: videoAreaMain1
width: 620
height: 470
color: "#000000"
Image {
id: imgVideo
width: parent.width
height: parent.height
anchors.left: parent.left
anchors.top: parent.top
fillMode: Image.PreserveAspectFit
MouseArea {
id: zooingWheeler
anchors.fill: parent
hoverEnabled: true
}
}
}
}
Thanks in advance.
Related
I am trying to make a Gomoku game using qml and c++. I have created a 10 * 10 board using qml grid and repeater. like this....
Window {
width: 640
height: 480
visible: true
color: "#241d2b"
title: qsTr("Hello World")
Grid {
x: 10; y: 10
width: 418
height: 418
property bool defineColor: true
rows: 10; columns: 10; spacing: 2
Repeater {
model: 100
Rectangle {
width: 40; height: 40
color: "white"
MouseArea{
anchors.fill: parent
TapHandler{
id:tapped
onTapped: ghuti.visible = uiBridge.showLog(index)
}
}
Rectangle {
id: ghuti
visible: false
radius: width*0.5
anchors.fill: parent
anchors.rightMargin: 5
anchors.leftMargin: 5
anchors.bottomMargin: 5
anchors.topMargin: 5
//anchors.fill: parent
color: "red"
}
Rectangle {
id: ghuti2
visible: false
radius: width*0.5
anchors.fill: parent
property string property0: "none.none"
anchors.rightMargin: 5
anchors.leftMargin: 5
anchors.bottomMargin: 5
anchors.topMargin: 5
//anchors.fill: parent
color: "black"
}
}
}
}
}
The human input can be easily captured by mouse click...but in reply, computer need to turn. But I do not find and clue for automatic computer turn in right place. The two rectangles inside the loop ...one is for human input and other is for computer input.`
I want to create a custom Scrollbar.Like this.
This is my code, i want to use ScrollBar component in Qml.
Rectangle {
id: frame
clip: true
width: 160
height: 160
border.color: "black"
anchors.centerIn: parent
Text {
id: content
text: "ABC"
font.pixelSize: 160
x: -hbar.position * width
y: -vbar.position * height
}
ScrollBar {
id: vbar
hoverEnabled: true
active: hovered || pressed
orientation: Qt.Vertical
size: frame.height / content.height
anchors.top: parent.top
anchors.right: parent.right
anchors.bottom: parent.bottom
}
}
In my case, i want to create with my Scrollbar image.
I tried「source: "./bar.bng" 」,but it said ScrollBar haven't have the parameter "source". How can i use custom image.
Stylesheets (in a form of .qss files, as used for QWidget's) are not used for QML.
Here are examples of how you can implement them though.
For your exact use-case, check out Customizing ScrollBar
I have a QML GridView with a scrollbar and hover effect, when I move the curso to the page's bottom the hover make an automatic scrolling, I want to stop it. I tried to set the interactive property of Flickable to false "interactive: false" but it didn't work. How can I stop this behavior?
Obs: When I remove the hover effect the scroll behave in the expected way, just moving through the scrollbar.
GridView{
id: grid
anchors.margins: 20
anchors.fill: parent
cellHeight: 80
cellWidth: 80
model: MyModel{}
highlight: Rectangle {
color: "lightsteelblue"
height: parent.cellHeight
width: parent.cellWidth
z:2
opacity: 0.7
}
delegate: Column {
Rectangle {
color: myColor;
height: grid.cellHeight * 0.7
width: grid.cellWidth * 0.7
border.color: "white"
anchors.margins: 5
anchors.horizontalCenter: parent.horizontalCenter
MouseArea {
id: mouseRegion
anchors.fill: parent
hoverEnabled: true
onEntered: grid.currentIndex = model.index
}
}
Text {
text: name;
anchors.horizontalCenter: parent.horizontalCenter }
}
}
Here is the Link to a simple project that reproduces the behavior: https://drive.google.com/open?id=0B7WUSCDDdwtIbWVDWVFvMjM1djA
My workmate help me to figured out a solution to my problem. I was using currentIndex property to set the hover position in the gridview, as described on documentation this property will smoothly scroll the GridView in the way that the current item becomes visible if the highlightFollowsCurrentItemis set to true (default value) and will not scroll if highlightFollowsCurrentItem set to false.
However, after set highlightFollowsCurrentItem property to false, the automatic scroll stopped together with my hover effect, which is clearly unwanted. I couldn't figure out what was wrong and we came out with a different approach.
To make the hover work without the automatic scrolling provided by currentIndex behavior, we remove it from gridview and used onEntered and onExited to control hover behavior, changing the rectangle visibility (id:selectedItem) used to simulate the hover effect as showed below.
GridView{
id: grid
anchors.margins: 20
anchors.fill: parent
cellHeight: 80
cellWidth: 80
model: MyModel{}
delegate: Item{
height: grid.cellHeight * 0.9
width: grid.cellWidth * 0.7
Rectangle {
id: selectedItem
color: "lightsteelblue"
height: parent.height
width: parent.width
z:12
opacity: 0.7
visible: false
}
Rectangle {
id:rect
color: myColor;
height: parent.height-textName.height
width: parent.width
border.color: "white"
anchors.margins: 5
anchors.horizontalCenter: parent.horizontalCenter
MouseArea {
id: mouseRegion
anchors.fill: parent
hoverEnabled: true
onEntered: selectedItem.visible = true
onExited: selectedItem.visible = false
}
}
Text {
id: textName
text: name;
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
}
}
}
It allowed me to avoid automatic scroll and keep the hover effect work properly.
I am trying to create a scroll view around a ColumnLayout, unfortunately my current code doesn't work. I know about ListView, but in my case I need to create scrollable Layout, because it will contain heterogeneous elements.
ApplicationWindow {
id: mainwindow
title: qsTr("Hello World")
width: 300
height: 300
visible: true
ScrollView {
anchors.fill: parent
ColumnLayout {
width: mainwindow.width
Image {
anchors.bottomMargin: 10
source: "img/button.jpg"
width: parent.width
height: 400
}
Image {
source: "img/button.jpg"
width: parent.width
height: 500
}
}
}
}
This renders to this (which is clearly not what I want):
There are two problems:
Images are not stretched across the entire window width, parent.width is ignored. I want images to have exact same width as ScrollView (no horizontal scroll)
Image height property is ignored
What am I doing wrong?
I would go with a plain column and access the desired width property directly by id. As I understand these container elements are measuring their size depending on their content, that might be the reason why setting the ColumnLayouts width has no effect.
This works for me:
ScrollView
{
anchors.fill: parent
Column {
Repeater {
model: 4;
delegate: Item {
width: root.width;
height: image.sourceSize.height;
Image {
id: image;
anchors.centerIn: parent;
width: parent.width;
fillMode: Image.Stretch;
source: "img" + (index+1) + ".png"
}
}
}
}
}
In my case root is just the parent's id. Hope this helps!
Same problem on my side. This worked for me :
ScrollView {
width: parent.width
height : parent.height
contentWidth: column.width // The important part
contentHeight: column.height // Same
clip : true // Prevent drawing column outside the scrollview borders
Column {
id: column
width: parent.width
// Your items here
}
}
In OpenGL terms, what I want to do is modify the projection matrix of a Qt GUI.
Pretend the window is 480x640. It is displayed as normal, and rendered to a texture.
I then take that texture, and stretch it across the entire screen.
Does Qt have something like that? I don't want the GUI looking fine and having appropriately-sized text on a 480x640 tablet, but then it gets loaded up on a 1536x2048 tablet and you need a magnifying glass for the text.
I've written my own GUI in OpenGL before, calculating a vid.width/BASEWIDTH, vid.height/BASEHEIGHT ratio and multiplying the modelview matrix of elements to ensure that a GUI always fills a screen and stays the same size -- obviously this only works perfectly providing the aspect ratio is the same, but I digress.
I messed with layouts in Qt Quick for awhile, and it offers some nice anchoring options, but nothing for stuff like scaling up the text if the parent window is larger. Or am I missing something here?
An OpenGL GUI I wrote had a few options for control position coordinates:
Origin for transforms (Top, Center, Bottom, Left, Center, Right)
PosIsPercentage (specified whether the position coordinates were to be interpreted as a percentage of screen width/height)
This allowed you to set the position as a distance from any edge of the screen, or you could set PosIsPercentage = true and set the X value to 75 to have the coordinate always be at 3/4ths of whatever the screen size was.
There was also a SizeIsPercentage value, so you could set a button to be 10% of the screen width.
I see some of these options in the Qt Quick designer, but they aren't behaving as I expect.
I know this is hard to explain, so here is an image to demonstrate:
http://www.spaddlewit.com/QtLayoutProblem.png
(not what I'm using Qt for, but a good example of the problem I'm having)
Scaling items based on the width and height of the screen works well enough, except when you move to a high DPI device. A better method is to scale items based on the height of the default font. The default font size of a Text item, for example, will always be legible on platforms supported by Qt, no matter the DPI. You can use the same principle to scale font sizes; multiply the default font size by some amount.
Below I've done a quick mock up of the screenshot you linked to:
import QtQuick 2.3
import QtQuick.Controls 1.2
ApplicationWindow {
id: window
contentItem.implicitWidth: 640
contentItem.implicitHeight: 480
contentItem.minimumWidth: 640
contentItem.minimumHeight: 480
contentItem.maximumWidth: 1024
contentItem.maximumHeight: 768
/*
With Qt 5.4, you can also use the new FontMetrics item,
which saves you the overhead of creating a Text item:
For example:
FontMetrics {
id: fontMetrics
}
Then:
font.pixelSize: fontMetrics.font.pixelSize * 4
anchors.margins: fontMetrics.implicitHeight * 2
*/
Text {
id: defaultText
}
Image {
source: "http://cdn2.landscapehdwalls.com/wallpapers/1/perfect-green-hills-1197-1280x800.jpg"
}
Item {
id: container
anchors.fill: parent
anchors.margins: defaultText.implicitHeight * 2
Column {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
spacing: container.anchors.margins
Text {
id: yourGameText
text: "Your Game!"
font.pixelSize: defaultText.font.pixelSize * 4
wrapMode: Text.Wrap
}
ListView {
interactive: false
anchors.right: parent.right
width: yourGameText.width
height: container.height * 0.3
model: ["Play Game!", "Options", "Exit"]
delegate: Button {
text: modelData
width: ListView.view.width
}
}
}
Row {
anchors.left: parent.left
anchors.bottom: parent.bottom
spacing: container.anchors.margins
Image {
source: "http://www.facebookbrand.com/img/assets/asset.f.logo.lg.png"
width: defaultText.implicitHeight * 3
height: width
}
Image {
source: "http://g.twimg.com/Twitter_logo_white.png"
width: defaultText.implicitHeight * 3
height: width
}
Image {
source: "http://www.youtube.com/yt/brand/media/image/YouTube-logo-full_color.png"
width: defaultText.implicitHeight * 3
height: width
}
}
}
}
Window Size
The first thing I did was set the default, minimum and maximum size of the window.
Scaling
Next, I created an empty Text item which items and text sizes will be based off. It might seem hackish, and it is a bit, but it also works really well. As mentioned in the comment, in Qt 5.4 there will be a FontMetrics type which you can use instead of creating a Text item that will never actually be shown.
Another alternative is to use Screen's pixelDensity property.
Margins
You said you wanted to:
set the position as a distance from any edge of the screen
I did that by creating an Item that fills the window, and then setting the margins from the edges of the window as some factor of the default font's implicit height. This ensures that the content within the item will be the same physical distance (e.g., in millimetres) from the edge of the window regardless of the DPI of the device you're viewing it on. If you'd rather the distance be larger if the window is larger, you can do this instead:
anchors.margins: window.width * 0.1
Font Sizes
Take a look at the Text item within the Column. If you want to ensure the text is also the same physical size on the screen, you can set font.pixelSize to be the default font's size multiplied by some amount. Again, if you'd rather base it off the size of the screen rather than the DPI, you can do this instead:
font.pixelSize: window.height * 0.05
More Information
The Scalability documentation also gives a nice overview on this topic.
Below is a screenshot of the application running:
The following works, but it's annoying -- you have to create a scaleWidth and scaleHeight function and wrap any constant coordinates in them.
Font sizes scale along the shortest edge of the screen -- this application is a Portrait-only orientation, so it uses scaleWidth(pointSize) for font sizes.
Would be nice to find a solution that's compatible with the QML designer.. is there any way to automatically insert this calculation, maybe afterwards in C++ code at runtime?
import QtQuick 2.2
import QtQuick.Window 2.1
import QtQuick.Controls 1.2
ApplicationWindow {
id:window
visible: true
width: 480
height: 640
function scaleWidth(w)
{
return w * (width / 480.0)
}
function scaleHeight(h)
{
return h * (height / 640.0)
}
Text {
id: defaultText
}
Image {
id: image1
x: 0
y: 0
width: window.width
height: window.height
fillMode: Image.Stretch
source: "http://cdn2.landscapehdwalls.com/wallpapers/1/perfect-green-hills-1197-1280x800.jpg"
Label {
id: lblTitle
x: 0
y: scaleHeight(8)
text: qsTr("Welcome to the App")
anchors.horizontalCenter: parent.horizontalCenter
font.pointSize: scaleWidth(36)
horizontalAlignment: Text.AlignHCenter
}
Label {
id: lblSubtitle
x: 0
text: qsTr("Login to Continue")
font.pointSize: scaleWidth(24)
anchors.top: lblTitle.bottom
anchors.topMargin: scaleHeight(8)
anchors.horizontalCenter: lblTitle.horizontalCenter
}
Item {
id: itemCenterAlign
x: 0
y: 0
width: 0
height: 200
anchors.horizontalCenter: parent.horizontalCenter
}
Label {
id: lblUsername
x: 0
text: qsTr("Username:")
anchors.top: lblSubtitle.bottom
anchors.topMargin: scaleHeight(64)
font.bold: true
font.pointSize: scaleWidth(24)
anchors.right: itemCenterAlign.left
anchors.rightMargin: scaleWidth(8)
}
TextField {
id: txtUsername
width: scaleWidth(224)
height: scaleHeight(43)
anchors.left: itemCenterAlign.right
anchors.leftMargin: scaleWidth(8)
anchors.top: lblSubtitle.bottom
anchors.topMargin: scaleHeight(64)
font.pointSize: scaleWidth(24)
placeholderText: qsTr("Username")
}
Label {
id: lblPIN
x: 0
y: scaleWidth(-8)
text: qsTr("PIN:")
font.bold: true
font.pointSize: scaleWidth(24)
anchors.topMargin: scaleHeight(12)
anchors.right: itemCenterAlign.left
anchors.rightMargin: scaleWidth(8)
anchors.top: lblUsername.bottom
}
TextField {
id: txtPIN
x: 0
y: 0
width: scaleWidth(224)
height: scaleHeight(43)
placeholderText: qsTr("PIN")
font.pointSize: scaleWidth(24)
anchors.topMargin: scaleHeight(8)
anchors.leftMargin: scaleWidth(8)
anchors.left: itemCenterAlign.right
anchors.top: txtUsername.bottom
}
Row {
id: row1
x: 0
y: scaleHeight(277)
width: scaleWidth(464)
height: scaleHeight(115)
spacing: scaleWidth(8)
anchors.horizontalCenter: parent.horizontalCenter
Button {
id: cmdQuit
text: qsTr("Quit")
width: row1.width / 3 - row1.spacing / 2
height: row1.height
}
Button {
id: cmdGPSOnly
text: qsTr("GPS Only")
width: row1.width / 3 - row1.spacing / 2
height: row1.height
}
Button {
id: cmdLogin
text: qsTr("Login")
width: row1.width / 3 - row1.spacing / 2
height: row1.height
}
}
Button {
id: cmdAbout
width: cmdQuit.width
height: scaleHeight(44)
text: qsTr("About")
anchors.top: row1.bottom
anchors.topMargin: scaleHeight(8)
anchors.left: row1.left
anchors.leftMargin: 0
}
Label {
id: lblVersion
y: 619
text: qsTr("v3.0.0.0")
font.pointSize: scaleWidth(16)
anchors.bottom: parent.bottom
anchors.bottomMargin: scaleHeight(8)
anchors.left: parent.left
anchors.leftMargin: scaleWidth(8)
}
Label {
id: lblBooks
x: 0
y: lvBooks.y
text: qsTr("Books Loaded:")
horizontalAlignment: Text.AlignRight
font.pointSize: scaleWidth(24)
anchors.right: lvBooks.left
anchors.rightMargin: scaleWidth(8)
}
Rectangle
{
x: lvBooks.x
y: lvBooks.y
width: lvBooks.width
height: lvBooks.height
color: "white"
border.color: "black"
}
ListView {
id: lvBooks
x: 0
y: 0
width: scaleWidth(224)
height: scaleHeight(160)
anchors.bottom: parent.bottom
anchors.bottomMargin: scaleHeight(8)
anchors.right: parent.right
anchors.rightMargin: scaleWidth(8)
model: ListModel {
ListElement {
name: "Book1"
}
ListElement {
name: "Book2"
}
}
delegate: Item {
x: 5
width: scaleWidth(80)
height: scaleHeight(40)
Row {
Text {
text: name
font.bold: true
font.pointSize: scaleWidth(24)
anchors.verticalCenter: parent.verticalCenter
}
spacing: 0
}
}
}
}
}