get cursor position in WebEngineView qml - qt

I have a program in Qt and a WebEngineView in it .I want to when my user clicked on a inputbox in webEngine a keyboard have been loaded and the inputbox get its contents from my keyboard (i wrote my own keyboard) but i can't do it .i try codes in bellow but don't work
WebEngineView {
anchors.fill:parent
id:webEng
url: "https://example.com"
visible: true
MouseArea {
id : mousearea
anchors.fill: parent
onClicked: {
mykeyboard.visible=true;
}
}
}

This is not a complete answer but this code could help:
import QtQuick 2.10
import QtWebView 1.1
import QtQuick.Controls 1.4
import QtWebEngine 1.7
Item {
width: 1280
height: 720
WebView { // or WebEngineView {
id: webview
width: 1280
height: 720
url: "http://google.com"
visible: true
onLoadingChanged: {
if (loadRequest.status === WebView.LoadSucceededStatus) {
console.log("Loaded!!")
webview.runJavaScript('
var input = document.getElementById("lst-ib");
input.addEventListener("click", function() {
alert("Clicked!");
});
'
)
}
}
}
Rectangle {
id: myDummyKeyboard
anchors.bottom: parent.bottom
width: parent.width
height: 100
color: "gray"
visible: true
border.width: 20
Button {
anchors.centerIn: parent
text: "Dummy"
onClicked: {
webview.runJavaScript('document.getElementById("lst-ib").value += "' + text + '"');
}
}
}
}
The part in the WebView (or WebEnginView) allows to display an alert when the input is clicked. But, something is missing, to link it to a QML handler. The solution is maybe to use WebChannel or maybe WebEngineScript as said by #folibis in the comments.
The part defined by myDummyKeyboard allows to add a string into the input when the user is clicking the button in the rectangle (fake keyboard).

Related

How should I start QML files?

I have 4 QML files: MainMenu.qml, AppArea.qml, Result.qml and main.qml.
When my app starts, I want to see first page as MainMenu.qml fullscreen. There is a button (on MainMenu.qml) to start AppArea.qml. When I click the the button, I want to start AppArea.qml as fullscreen new window.
There is a button (on AppArea.qml), when I click that button, I want to show Result.qml but I want to see Result.qml on AppArea.qml, I mean when Result.qml come outs, AppArea.qml will not disappear but Result.qml will appear on AppArea.qml.
There is a button on Result.qml. When I click the button, the Repeater in AppArea.qml will regenerate, because maybe model of Repeater changing like 1, 2, 3, 4.... There is a button on AppArea.qml, when I click the button, I want to open MainMenu.qml as a fullscreen new window like AppArea.qml.
Actually you can think basic: My app is a game like this:
How way should I choose for these jobs?
In addition to the mentioned post, in your case you are using the component from qml file, so you need to load the component first, your main.qml can be like this:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
Window {
id: mainWindow
title: "Main window"
visible: true
flags: Qt.Dialog
modality: Qt.ApplicationModal
Loader{
id: mainMenuLoader
}
Component.onCompleted: {
mainMenuLoader.source="mainMenu.qml"
var mainMenu = mainMenuLoader.item.createObject(mainWindow);
mainWindow.hide()
}
}
and your mainMenu.qml can look like this:
import QtQuick 2.9
import QtQuick.Window 2.3
import QtQuick.Controls 2.2
Component {
id: mainMenu
Window {
id:mmenu
title: "Main Menu"
width: 600
height: 600
visible: true
flags: Qt.Dialog
modality: Qt.ApplicationModal
Loader{
id: appAreaLoader
}
Text {
text: "This is mainMenu"
}
Button{
id: loadAppArea
anchors.centerIn: parent
text: "Start Game"
onClicked: {
appAreaLoader.source="appArea.qml"
var appArea = appAreaLoader.item.createObject(mainMenu);
hide()
}
}
}
}
you will need to do the same for successive windows ...etc.
While for result, you need to use a MouseArea:
appArea.qml:
Component {
id: appMenu
Window {
id:appMenuWindow
title: "App Menu"
width: 600
height: 600
visible: true
flags: Qt.Dialog
modality: Qt.ApplicationModal
Loader{
id:anotherLoader
visible: true
anchors.left: appMenuText.left
anchors.top: appMenuText.bottom
width: parent.width/3
height: parent.height/3
}
Text {
id: appMenuText
text: "This is App Area"
anchors.centerIn: parent
}
Button{
id: loadResult
text: "Show Result"
onClicked: {
anotherLoader.source = "result.qml"
anotherLoader.visible=true
}
}
Button{
anchors.right: parent.right
id: loadMainMenu
text: "Open main Menu"
onClicked: {
hide()
//mmenu.show()
anotherLoader.setSource("main.qml")
}
}
}
}
result.qml:
Rectangle{
color: "green"
Text {
anchors.centerIn: parent
id: resultxt
text: qsTr("This is result, Click to close")
}
MouseArea {
anchors.fill: parent
onClicked: { anotherLoader.visible = false
}
}
}

How to implement swipeview QtQuick 2.5

I have QT 5.5 and it won't support SwipeView. I tried doing with listView but I am not getting what I expected. I want a similar functionality code in QT 5.5 like the code given below which is written in QT 5.6. Please help
import QtQuick 2.6
import QtQuick.Controls 2.0
import QtQuick.Window 2.0
Window {
visible: true
width: 200
height: 400
title: qsTr("Hello World")
id: page
SwipeView {
id: swipeView
anchors.fill: parent
currentIndex: 0
Page {
Label {
text: qsTr("First page")
anchors.centerIn: parent
}
}
Page {
Label {
text: qsTr("Second page")
anchors.centerIn: parent
}
}
Page {
Label {
text: qsTr("Third page")
anchors.centerIn: parent
}
}
Page {
Label {
text: qsTr("Fourth page")
anchors.centerIn: parent
}
}
Page {
Label {
text: qsTr("Fifth page")
anchors.centerIn: parent
}
}
}
Rectangle
{
id:minus
width:parent.width/2
height:100
anchors.left:parent.left
anchors.bottom:parent.bottom
color:"red"
MouseArea
{
anchors.fill:parent
onClicked:{
if(swipeView.currentIndex>0)
swipeView.currentIndex--
}
}
}
Rectangle
{
id:plus
width:parent.width/2
height:100
anchors.right:parent.right
anchors.bottom:parent.bottom
color:"green"
MouseArea
{
anchors.fill:parent
onClicked:{
if(swipeView.currentIndex<4)
swipeView.currentIndex++
}
}
}
}
If you cannot update your Qt version, you can indeed approximate a SwipeView using a ListView, a VisualItemModel, and a default qml property.
SwipeView.qml
ListView
{
id: root
// Allow to add pages as you would for a QtQuick.Controls 2 SwipeView
// Each item you declare in your SwipeView will be reparented to itemModel
default property alias items: itemModel.children
// SwipeView is horizontal
orientation: Qt.Horizontal
// Hide out of bounds pages
clip: true
// Do not stop between two pages
snapMode: ListView.SnapToItem
// Update currentIndex as you swipe through the pages
highlightRangeMode: ListView.StrictlyEnforceRange
model: VisualItemModel {
id: itemModel
// Used to bind the pages size to the swipeView size
onChildrenChanged: {
for(var i=0;i<children.length; i++)
{
children[i].width = Qt.binding(function(){return root.width})
children[i].height = Qt.binding(function(){return root.height})
}
}
}
}
Page.qml
Item {
property string title
Rectangle
{
anchors.fill: parent
border.width: 1
}
Text
{
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: 20
text: title
}
}
PageIndicator.qml
Row
{
id: root
property int count
property int currentIndex
property Component delegate: bullet
property bool interactive
spacing: 5
Component
{
id: bullet
Rectangle
{
height: 10
width: height
radius: height/2
color:"black"
opacity: currentIndex==index?0.8:0.2
}
}
Repeater
{
model: root.count
Loader
{
property int index: model.index
sourceComponent: delegate
}
}
}
main.qml
import QtQuick 2.5
import QtQuick.Controls 1.4
ApplicationWindow
{
id: window
visible: true
width: 300
height: 300
SwipeView
{
id: swipeView
anchors.fill: parent
Page
{
title: "Page 1"
}
Page
{
title: "Page 2"
}
Page
{
title: "Page 3"
}
}
PageIndicator
{
id: pageIndicator
anchors.bottom: swipeView.bottom
anchors.bottomMargin: 10
anchors.horizontalCenter: swipeView.horizontalCenter
count: swipeView.count
currentIndex: swipeView.currentIndex
}
}
Qt Quick Controls 2 was introduced in Qt 5.7:
Qt Quick Controls 2 provides a set of controls that can be used to build complete interfaces in Qt Quick. The module was introduced in Qt 5.7.
Qt Labs Controls was introduced in Qt 5.6, so the code that you referenced would have to use the Qt.labs.controls 1.0 import in order to run with Qt 5.6.
You need to use a newer Qt version (5.6 or newer).

QML BusyIndicator while loading a heavy qml file

I've been trying to run a BusyIndicator (http://doc.qt.io/qt-5/qml-qtquick-controls-busyindicator.html) while I am loading a qml file (http://doc.qt.io/qt-5/qml-qtquick-loader.html), but the BusyIndicator doesn't appear.
What I am trying to do is:
1- The user emits a "handlerLoader(name)", where "name" is the url of the next qml page.
2- In "onHandlerLoader" I run the busyIndicator.
3- Then, I change the Loader source.
The problem is that no matter the time I spent between steps 2 and 3, the BusyIndicator does not appear.
Moreover, when I comment step 3, the busyIndicator appears correctly.
What I am doing wrong?
Thanks!!
This is the code:
Rectangle {
visible: true
width: 800
height: 480
signal handlerLoader (string name)
Loader {
id: pageLoader;
source: "init.qml";
}
BusyIndicator {
id: busyIndicator_inicio
width: 100
height: 100
anchors.centerIn: parent
running: false
}
Connections {
target: pageLoader.item
onHandlerLoader: {
busyIndicator_inicio.running = true
pageLoader.source = name;
}
}
}
The reason is, that your heavy-loading Loader is blocking the thread.
Set it to asynchronous mode, to allow the rest of the program to run.
Further, I'd recommend to prefer declarative bindings to imperative assignments in handlers. See my example:
main.qml:
import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
Window {
width: 1000
height: 800
visible: true
Button {
text: 'load'
onClicked: {
loader.source = "TestObj.qml"
}
}
Loader {
anchors.fill: parent
id: loader
active: true
asynchronous: true
visible: status == Loader.Ready
}
BusyIndicator {
id: ind
anchors.fill: parent
running: loader.status == Loader.Loading
}
}
TestObj.qml:
import QtQuick 2.0
Item {
Grid {
anchors.fill: parent
columns: width
rows: height
Repeater {
model: 100
Rectangle {
width: { for (var i = 0; i < 10000; i++) console.log(i); return 1 }
height: 1
color: 'green'
}
}
}
}
Since the asynchronous Loader might display incomplete files for some time, I set it to be visible only when its status changes to ready.

How to use mouseclick area from loaded Form in qml?

below is my code snippet where i'm loading qml ui using dynamic object creation method now i have to implement mousearea which reside in loaded file, can anyone help me to do this
Qt.createQmlObject(" import QtQuick 2.0
Loader {
id: pageLoader
source: '/HomeScreenForm.ui.qml'
anchors.fill: parent
anchors.rightMargin: 0
anchors.leftMargin: 0
anchors.bottomMargin: parent
anchors.topMargin: parent
}
", rectangle7)
Create custom item contains MouseArea. To make the area accessible from outside you can use alias, for example:
MyItem.qml
import QtQuick 2.7
Rectangle {
id: root
color: "yellow"
property alias area: mouseArea
MouseArea {
id: mouseArea
anchors.fill: parent
}
Text {
anchors.centerIn: parent
text: "Click me!"
}
}
And then you can create it dynamically:
import QtQuick 2.7
import QtQuick.Window 2.0
Window {
id: mainWindow
width: 600
height: 600
visible: true
Component.onCompleted: {
var component = Qt.createComponent("MyItem.qml");
if (component.status === Component.Ready) {
var obj = component.createObject(mainWindow);
obj.width = 200;
obj.height = 200;
obj.anchors.centerIn = mainWindow.contentItem;
obj.area.onPressed.connect(
function(mouse){
console.log("pressed at (", mouse.x,",",mouse.y,")")
});
}
}
}
Another way is using Connections, as #derM already noticed.

How to make visible both icon and text on QML ToolButton

I am creating desktop application using QML and QtQuick.Components. I want to place on the toolbar buttons like the standard MacOS settings dialogs do:
I use ToolBar and ToolButton, but I can't find the way to do it. For instance with the following code it shows icons only:
ApplicationWindow {
// ...
toolBar: ToolBar {
RowLayout {
ToolButton {
text: qsTr("Main")
iconSource: "main.png"
}
ToolButton {
text: qsTr("System")
iconSource: "system.png"
}
ToolButton {
text: qsTr("Items Book")
iconSource: "itemsbook.png"
}
}
}
}
And it seems like ToolButton can show either text or icon:
Text {
id: textitem
text: button.text
anchors.centerIn: parent
visible: button.iconSource == "" // <=========
}
A simple yet a powerful approach is to create own QML component.
Create a custom QML component / file:
File -> New File or Project -> Qt -> QML File (choose latest version).
Now enter file name, for example MyToolButton.
Note that it will be also used as
component name.
Add there neccesary imports and code:
MyToolButton.qml (customize for your needs)
import QtQuick 2.0
import QtQuick.Controls 1.4
ToolButton
{
Image {
source: parent.iconSource
fillMode: Image.PreserveAspectFit // For not stretching image (optional)
anchors.fill: parent
anchors.margins: 2 // Leaving space between image and borders (optional)
anchors.bottomMargin:10 // Leaving space for text in bottom
}
Text {
text: parent.text
anchors.bottom: parent.bottom // Placing text in bottom
anchors.margins: 2 // Leaving space between text and borders (optional)
anchors.horizontalCenter: parent.horizontalCenter // Centering text
renderType: Text.NativeRendering // Rendering type (optional)
}
}
Main.QML (where you want to use it):
import QtQuick 2.0
import QtQuick.Controls 1.4
// Usual toolbar declaration
ToolBar {
id: mainToolBar
RowLayout {
// Create MyToolButton. Note that component name (MyToolButton) is the same as file name.
MyToolButton {
id:tbQuit
// Way 1: Add here any icon
iconSource: "qrc:///images/quit.png"
text:qsTr("&Quit")
// Way 2, my favourite: Convert your Action into Button!
action: actQuit
}
}
}
Action {
id: actQuit
text: qsTr("&Quit")
onTriggered: Qt.quit()
shortcut: "Alt+Q"
iconSource: "qrc:///Images/Exit.png"
}
Notes:
It requires QtQuick.Controls 1.4 and should work on Qt 5.2+. (Worked fine on Qt 5.5).
Don't forget to add imports.
Code parts marked as (optional) can be skipped.
Replace ToolButton with Button and it will work as a Button.
Hope it helps!
Have you try to add your own Text control like this:
ApplicationWindow {
// ...
toolBar: ToolBar {
RowLayout {
ToolButton {
text: qsTr("Main")
iconSource: "main.png"
Text {
text: parent.text
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
}
}
ToolButton {
text: qsTr("System")
iconSource: "system.png"
Text {
text: parent.text
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
}
}
ToolButton {
text: qsTr("Items Book")
iconSource: "itemsbook.png"
Text {
text: parent.text
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
}
}
}
}
}
And set the ToolButton height with the right value (image + text height)

Resources