QT/QML Business logic separated from the UI - qt

I'm trying to put the business logic in Main.qml and the UI in MainForm.ui.qml but I can't connect both by widget id.
MainForm.ui.qml:
import QtQuick 2.8
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
Page {
id: page
header: TabBar { ... }
StackLayout {
id: stack
Pane {
Flow {
TextField {
id: theText
}
property alias sendBtn: sendBtn
Button {
id: sendBtn
}
}
}
}
}
Main.qml:
import QtQuick 2.8
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
MainForm {
anchors.fill: parent
sendBtn {
onClicked: backend.sendTextToServer( theText.text )
}
}
}
Qt Creator says : Invalid property name "sendBtn" (M16)
Running failed with the following messages:
QQmlApplicationEngine failed to load component
qrc:/Main.qml:12 Cannot assign to non-existent property "sendBtn"

when you put property alias sendBtn: sendBtn inside Pane is interpreted as being a Pane property so you can not access it that way, it is correct to place it in the context of Page.
import QtQuick 2.8
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
Page {
id: page
property alias sendBtn: sendBtn
property alias theText: theText
header: TabBar { ... }
StackLayout {
id: stack
Pane {
Flow {
TextField {
id: theText
}
Button {
id: sendBtn
}
}
}
}
}

Related

try to access qml global variable, but it reports error

my code
AppDelegate.js for global variables
.pragma library
var appDelegate= {}
MyApp.js
Qt.include("AppDelegate.js")
function AppDelegate(){
}
AppDelegate.prototype.doSomething=function() {
console.log("vvvvvvvvvvvvv")
}
AppDelegate.prototype.doSomething1=function() {
console.log("AAAAAAAAAAAAAA")
}
//-------------------------------------------------------
function initApp(){
appDelegate=new AppDelegate()
appDelegate.doSomething()
appDelegate.doSomething1()
}
MyApp.qml
import QtQuick 2.2
import QtQuick.Controls 1.2
import "MyApp.js" as MyApp
ApplicationWindow {
visible: true
title: "System Dialogs Gallery"
width: 580
height: 480
TabView {
anchors.fill: parent
anchors.margins: 8
Tab {
id: controlPage
title: "File"
FileDialogs { }
}
}
Component.onCompleted: {
MyApp.initApp()
}
}
it works well and output is
qml: vvvvvvvvvvvvv
qml: AAAAAAAAAAAAAA
but if I call from other .js .qml file
ColorDialogs.js
Qt.include("AppDelegate.js")
function doit(){
appDelegate.doSomething1()
}
ColorDialogs.qml
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Dialogs 1.1
import "ColorDialogs.js" as ColorDialogs
Item {
Component.onCompleted: {
ColorDialogs.doit()
}
}
it reports error:
ColorDialogs.js: : TypeError: Property 'doSomething1' of object [object Object] is not a function
Your comment welcome
----------------------------updated

QML Button press and release color

Following is the sample Button QML code that I found in google:
Button {
id: myButton
text: "btnTxt";
function buttonClick()
{
console.log("Button "+ myButton.text +" is clicked!")
}
MouseArea {
id: myMouseId
anchors.fill: parent
onClicked:
{
myButton.buttonClick();
}
}
style: ButtonStyle {
background:
Rectangle {
color: myMouseId.pressed ? "#336699" : "#0099FF";
radius: 1;
}
}
}
And I am using the following imports:
import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.4
But, Qt threw the error:
Invalid property assignment: "pressed" is a read-only property
Also, is there an complete example for this basic type? I couldn't find in the doc how to address the above condition.

Adding TabButton dynamically to TabBar in QML

I am trying to add a tabButton to TabBar dynamically on pressing a button but i have spent a lot of time searching but i am not getting how to add, below is the code which i am working on :
MyTabButton.qml
import QtQuick 2.4
import QtQuick.Controls 2.2
Item
{
property int BtnWidth:0
property int BtnHeight:0
property string BtnText: ""
property bool isChecked : false
TabButton
{
id:tabBtn
text:BtnText
width:BtnWidth
height:BtnHeight
}
}
MainForm.qml
import QtQuick 2.4
import QtQuick.Controls 2.2
Rectangle
{
Button
{
id:button
width:100
height:100
anchors.top:parent.top
text:qStr("Add")
onClicked{
//How to add logic here to add tab in below tabBar.
}
}
TabBar
{
id:tabBar
anchors.top:button.bottom
width:500
height:500
}
}
Example:
import QtQuick 2.7
import QtQuick.Controls 2.0
ApplicationWindow {
id: window
width: 360
height: 630
visible: true
header: TabBar {
id: tabBar
}
Component {
id: tabButton
TabButton { }
}
Button {
text: "Add"
anchors.centerIn: parent
onClicked: {
var tab = tabButton.createObject(tabBar, {text: "Tab " + tabBar.count})
tabBar.addItem(tab)
}
}
}
You need to have something like a Component that is a TabButton. Your file MyTabButton.qml won't result in a TabButton, but instead an Item containing a TabButton, but with this, your TabBar does not know what to do.
So your file will need to have TabButton as root element
//MyTabButton.qml
import QtQuick 2.4
import QtQuick.Controls 2.2
TabButton
{
id: tabBtn
// customize as you like
}
Then you create a Component of this in your file where you want to use it. (e.g. main.qml)
import QtQuick 2.4
import QtQuick.Controls 2.0
ApplicationWindow {
width: 800
height: 600
visible: true
TabBar {
id: tabBar
width: 800
height: 50
}
// The component is like a factory for MyTabButtons now.
// Use myTabButton.createObject(parent, jsobject-with-property-assignments) to create instances.
Component {
id: myTabButton
MyTabButton {
/// EDIT ACCORDING TO YOUR COMMENTS ***
Connections {
target: tabBar
onCurrentIndexChanged: doSomething()
}
/// EDIT OVER
}
}
Button {
anchors.centerIn: parent
// Create a object out of the component, and add it to the container
onClicked: tabBar.addItem(myTabButton.createObject(tabBar /*, { object to set properties }*/))
}
}
TabBar inherits Container, which has addItem().
Try it in Window
Row {
anchors.fill: parent
TabBar {
id: tabBar
currentIndex: 0
width: parent.width - addButton.width
TabButton { text: "TabButton" }
}
Component {
id: tabButton
TabButton { text: "TabButton" }
}
Button {
id: addButton
text: "+"
flat: true
onClicked: {
tabBar.addItem(tabButton.createObject(tabBar))
console.log("added:", tabBar.itemAt(tabBar.count - 1))
}
}
}

Interaction between two QML files

I want to use some qml file(main.qml) but before that I need to get some authentication info from user(login, pass). So I want to do this in the second window(login.qml). I saw Qt.createComponent for opening second qml file, but I can't get any information from this type of window.
So how can I use some information from the second window in the first window?
Or how can I dynamically load these items(main.qml, login.qml) in the parent qml file?
So how can I use some information from the second window in the first
window?
This is just one way of doing it:
main.qml
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1
ApplicationWindow {
width: 400
height: 400
visible: true
ColumnLayout {
id: logItems
height: 200
Button {
id: loginButton
onClicked: loginForm.visible = true
text: "Log in"
}
Login {
anchors.top: loginButton.bottom
id: loginForm
visible: false
onLoginInfo: {
logInfo.text = "User:" + user + " password: " + password
}
}
}
Text {
id: logInfo
anchors.top : logItems.bottom
}
}
Login.qml
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1
Item {
signal loginInfo(string user, string password)
ColumnLayout {
RowLayout {
TextField {
id: user
}
TextField {
id: password
}
}
Button {
text: "Submit"
onClicked: loginInfo(user.text, password.text)
}
}
}
How can I dynamically load QML items from separate files/resources in
another QML file?
Qt.CreateComponent allows you to use JavaScript to dynamically create and use QML code from other files.

How to edit App menu from Qt Creator?

I start "QML App with controls" project in Qt Creator. I see that I can add to canvas different kind of controls, but I do not see how I can in graphical mode edit menu like: File, View, Edit... In constructor on canvas it's simple do not exists, but it's exists of running app, like http://img.ctrlv.in/img/15/10/03/560f856edb26c.png
You can create the menu in the main.qml file, here is an example application:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
ApplicationWindow {
title: qsTr("Hello World")
width: 640
height: 480
visible: true
menuBar: MenuBar {
Menu {
title: qsTr("&File")
MenuItem {
text: qsTr("&Open")
onTriggered: messageDialog.show(qsTr("Open action triggered"));
}
MenuItem {
text: qsTr("Save")
onTriggered: messageDialog.show(qsTr("Save action triggered"));
}
}
Menu {
title: qsTr("&Help")
MenuItem {
text: qsTr("About")
onTriggered: messageDialog.show(qsTr("About: test QML app with menu"));
}
}
}
MainForm {
anchors.fill: parent
button1.onClicked: messageDialog.show(qsTr("Button 1 pressed"))
button2.onClicked: messageDialog.show(qsTr("Button 2 pressed"))
}
MessageDialog {
id: messageDialog
title: qsTr("Message Test")
function show(caption) {
messageDialog.text = caption;
messageDialog.open();
}
}
}

Resources