Why QML MediaPlayer/VideoOutput doesn't work for me? - qt

I'm trying to play test video with qml by this code:
import QtQuick 2.2
import QtMultimedia 5.0
Item {
width: 300
height: 300
MediaPlayer {
id: player
source: "C:\\Downloads\\video.mp4"
}
VideoOutput {
id: video
anchors.fill: parent
source: player
}
MouseArea {
anchors.fill: parent
onPressed: player.play()
}
}
But, when I click on view, nothing happens. And if I change onPressed event to something else action (not with the player), it works fine, then it's not a MouseArea problem.
Where did I wrong?
Thank you.

The file path seems to be wrong. Since baclslashes need to be escaped in string litterals, the actual path remaining is:
c:\Downloads\video.mp4
That's a path, but not an URL. The correct URL is (see File URIs in Windows):
file:///C:/Downloads/video.mp4

On your code source:
C:\\Downloads\\video.mp4
should be source:
C://Downloads//video.mp4

Related

how to get the full URL from a QML WebView

When clicking on a link inside of a QT Quick WebView (something like "http://example.com/page?abc=def&bca=fde"), the url property doesn't contain the query string (giving only "http://example.com/page").
I tried console.log(webView.url) (webView being the ID of my WebView component) expecting it to be "http://example.com/page?abc=def&bca=fde", the result was "http://example.com/page" instead
Is there a way to get the query part?
I don't know exactly what you are doing, but it works correctly in my example. I'm using Qt 6.4.0.
Steps to reproduce:
Start example application
Type in qt in the google search field
Hit enter
Click on the image tab
View link with query part
The output will look as follows
qml: URL https://www.google.com/search?q=qt&source=lnms&tbm=isch&sa=X&ved=2ahUKEwiLxPKM4NX8AhVzS_EDHXYmAkwQ_AUoAXoECAEQAw&biw=800&bih=600
qml: LOAD https://www.google.com/search?q=qt&source=lnms&tbm=isch&sa=X&ved=2ahUKEwiLxPKM4NX8AhVzS_EDHXYmAkwQ_AUoAXoECAEQAw&biw=800&bih=600
Here is the code
import QtQuick
import QtWebView
Window {
id: root
width: 800
height: 600
visible: true
title: qsTr("Hello WebView")
WebView {
id: webView
anchors.fill: parent
url: "https://www.google.com"
onUrlChanged: console.log("URL", webView.url)
onLoadingChanged: function(loadRequest) {
console.log("LOAD", loadRequest.url)
if (loadRequest.errorString)
console.error(loadRequest.errorString);
}
}
}

Showing a busy indicator or a loading image while loading large QML file

I'm working on a QML based app. where I dynamically load the content. However when running the application it takes quite a long time (5-10 secs), so I need to show any loading screen or indicator while the whole content is being loaded. Can anyone suggest me how to do it ?
For example, after I login in my application it took some time to load the next page so within that oeriod of time i want to show the loading screen.
App {
id: app
height: 400
width: 200
Rectangle {
id: rectangle
Button {
id: button
text: qsTr("GO TO NEXT PAGE")
onClicked:stackView.push("page2.qml")
}
Image {
id: image
fillMode: Image.PreserveAspectFit
source: "default-app.png"
}
}
}
Suppose this is my code then where can i use loader ? I never used it before
You can use the status from a Loader component (I'm guessing you are using that since you are loading "dynamically"). Then use that in a BusyIndicator.
Loader {
id: loader
asynchronous: true
...
BusyIndicator {
anchors.centerIn: parent
running: loader.status == Loader.Loading
}
}
Heck, the Qt docs for BusyIndicator should have get you going!

How to access containing QML StackView?

I am new to QML, I have a Component which is pushed on a StackView. I'd like from this component to access the StackView containing it.
Here is a code that works
import QtQuick 2.11
import QtQuick.Controls.2.2
ApplicationWindow {
id: window
StackView {
id: stackView
initialItem: test1
anchors.fill: parent
}
Component {
id: test1
Button {
text: "Go to test2"
onClicked: stackView.push(test2)
}
}
Component {
id: test2
Button {
text: "Back to test1"
onClicked: stackView.pop()
}
}
}
However, I'd like to avoid accessing stackView by its id
Stack.view seems to be what I'm looking for, but I have no idea how to use it. I tried all of the following (replacing Buttons' onClicked) :
Stack.view.push(test2)
view.push(test2)
test1.Stack.view.push(test2)
test1.view.push(test2)
None of these work.
Am I misunderstanding something ? How am I supposed to use Stack.view ?
Edit : this question looks really close to mine : Access QML StackView from a control
I could indeed use a property to keep a reference to my StackView, but I would still like to avoid that if possible.
The accepted answer says that root.StackView.view.pop() is the correct method. I assume root is the Page's id from this post, so I tried test1.StackView.view.push(test2), but this still doesn't work. (Also tried with root, but it's not better)
Be aware that this Q/A is about the QtQuick.Controls 2.x
I also think it is good style to first use the attached property, rather than doubling this functionality by adding own, custom properties.
The problem is, that you are using the attached property in the wrong place - it is attached to the Item that is pushed onto the StackView and not to any of its children. So to use the attached property, you need to specify an identifier of this Item first.
In the example, that has been linked, this is root. But it is not the id of the Component-object. It has to be the root-node of the content of the Component-object.
You should have something like this:
Component {
id: myComponent
Item { // The Page. To this the attached property will be attached.
id: myComponentRoot // Use this to identify the root node of the pushed item.
Item { // Some more layers ...
...
Button { // Here you now want to access it perhaps?
onClicked: myComponentRoot.StackView.view.pop() // Reference the root node of the component to access it's attached properties.
}
}
}
}
A simple way of convenient using StackView.view is by assigning it to a property. In the following, I deliberately did not give the parent StackView an id. I can create a property in the sub-pages to grant access to the StackView as follows:
property StackView stackView: StackView.view
Here's a fully working example:
import QtQuick
import QtQuick.Controls
Page {
StackView {
anchors.fill: parent
initialItem: "Test1.qml"
}
}
//Test1.qml
import QtQuick
import QtQuick.Controls
Page {
property StackView stackView: StackView.view
Button {
anchors.centerIn: parent
text: "Go to test2"
onClicked: stackView.push("Test2.qml")
}
}
//Test2.qml
import QtQuick
import QtQuick.Controls
Page {
property StackView stackView: StackView.view
Button {
anchors.centerIn: parent
text: "Back to test1"
onClicked: stackView.pop()
}
}
You can Try it Online!

QML ListView method positionViewAtEnd() does exactly the opposite

I'm going crazy. I have a ListView inside a ScrollView, hooked up to a model that inherits QAbstractListModel. When objects are added to the model, the ListView shows them using a delegate. So far, so good.
But I really want the view to stay scrolled to the bottom (like a chat window), and I'm having a very difficult time making that happen. Here is the relevant QML code:
Rectangle {
ScrollView {
[anchor stuff]
ListView {
id: messageList
model: textMessageFiltered
delegate: messageDelegate
}
}
TextField {
id: messageEditor
[anchor stuff]
onAccepted: {
controller.sendTextMessage(text)
text = ""
/* This works. */
//messageList.positionViewAtEnd();
}
}
Component {
id: messageDelegate
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
color: "white"
height: nameText.height + 4
Text {
id: nameText
wrapMode: Text.Wrap
text: "<b>" + authorName + " (" + authorId + ")</b> " + message
[anchor stuff]
}
ListView.onAdd: {
console.log("This prints just fine!")
messageList.positionViewAtEnd()
}
}
}
}
The really strange thing, is that messageList.positionViewAtEnd() (at the end of the file) actually jumps it to the beginning. Without the call, the view stays where it is, even as new entries appear in the list. And indeed, if you look at the Qt documentation for the ListView.positionViewAtEnd(), it says:
Positions the view at the beginning or end, taking into account ...
Is that a silly error in the documentation, or what? I've tried everything I can think of to make this work, particularly the positionViewAtIndex() method and using highlighters to force the scroll to happen. But nothing works. Note the /* This works. */ comment in the source code above. When that is enabled, it works totally fine! (except of course, it jumps to the ListView.count()-2 index, instead of the end of the list)
Does anyone have any idea what might be wrong here? Any examples I could try to prove that there's a terrible, terrible bug in QML?
I'm using Qt 5.3.1 with QtQuick 2.0 (or 2.1 or 2.2 fail too). I've tried many, many other configurations and code as well, so please ask if you need more info. I've completely exhausted my google-fu.
Thanks!
Edit 1
While the accepted answer does solve the above problem, it involves adding the Component.onCompleted to the delegate. This seems to cause problems when you scroll the list, because (I believe) the delegates are added to the view when you scroll up, causing the onCompleted trigger to be called even if the model item isn't new. This is highly undesirable. In fact, the application is freezing when I try to scroll up and then add new elements to the list.
It seems like I need a model.onAdd() signal instead of using the existence of a delegate instance to trigger the scroll. Any ideas?
Edit 2
And how does this NOT work?
ListView {
id: messageList
model: textMessageFiltered
delegate: messageDelegate
onCountChanged: {
console.log("This prints properly.")
messageList.positionViewAtEnd()
}
}
The text "This prints properly" prints, so why doesn't it position? In fact, it appears to reset the position to the top. So I tried positionViewAtBeginning(), but that did the same thing.
I'm totally stumped. It feels like a bug.
You need to set the currentIndex as well.
testme.qml
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Window 2.0
ApplicationWindow {
title: qsTr("Hello World")
width: 300
height: 240
ScrollView {
anchors.fill: parent
ListView {
anchors.fill: parent
id: messageList
model: messageModel
delegate: Text { text: mytextrole }
highlight: Rectangle { color: "red" }
highlightMoveDuration: 0
onCountChanged: {
var newIndex = count - 1 // last index
positionViewAtEnd()
currentIndex = newIndex
}
}
}
ListModel {
id: messageModel
ListElement { mytextrole: "Dog"; }
ListElement { mytextrole: "Cat"; }
}
Timer {
property int counter: 0
running: true
interval: 500
repeat: true
onTriggered: {
messageModel.append({"mytextrole": "Line" + (counter++)})
}
}
}
There is still some jumping to the first element and jumping back down for a fraction of a second.
There is a note in documentation:
Note: methods should only be called after the Component has completed. To position the view at startup, this method should be called by Component.onCompleted.
Change your ListView.onAdd: to
Component.onCompleted: {
console.log("This prints just fine!")
messageList.positionViewAtEnd()
}
And it works well.
In your case, the ListView emits add signal before the new delegate is created and completed. The ListView is still working on something behind the scene, so positionViewAtEnd cannot work as expected. And /* This works. */ because it is called after the new delegate is completed. However, don't assume this always works. Simply follow the note, call positionViewAtEnd in Component.onCompleted, in documentation.

to pause and resume caputured webcam video (Qtmultimedia 5.0-qml-ubuntu)

I am using Qtmultimedia 5.0 to record and capture video from webcam. The example provided by Qt helped me very much. I could record and stop the captured video using the following code.
Camera {
id: camera
}
Rectangle{
Text{
text: qsTr("Record")
}
MouseArea{
onClicked: camera.videoRecorder.record()
}
}
Rectangle{
Text{
text: qsTr("Stop")
}
MouseArea{
onClicked: camera.stop()
}
}
Now i need the pause and resume the webcam video. Is there any function to do that job. If I resume the video it should append to the opened file.
just want to let you know that you can use Qt Media Encoding Library for that task.
It is here - http://kibsoft.ru

Resources