Dynamically adding TabButton to TabBar - qt

I am trying to add a TabButton to a TabBar dynamically. My new tab is in a file called Network, and my GWEdit_101 descends from a class with a TabBar. When the code runs and tries to add the tab it errors on the addItem line below. I can't figure out the cause/solution.
My file Network.qml is:
import QtQuick 2.0
import QtQuick.Controls 2.12
TabButton {
id: tabNetwork
contentItem: Text {
text: qsTr("NewStuff")
opacity: enabled ? 1.0 : 0.3
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
}
My file GWEdit_101.qml is:
import QtQuick 2.0
import QtQuick.Controls 2.12
GWEdit {
Component.onCompleted: {
tabBar.addItem(Network)
}
}
Results in this error
"Could not convert argument 0 at"
"onCompleted#qrc:/content/equipment/gateway/edit/makemodels/GWEdit_101.qml:6"

You must use Qt.createQmlObject since Network is a component, not an item.
TabBar {
id: tabBar
Component.onCompleted: {
var tabItem = Qt.createQmlObject('Network{}', tabBar)
tabBar.addItem(tabItem);
}
}
Fore more information please read: Dynamic QML Object Creation from JavaScript.

Related

Qml menu popup latency

When my mouse event happened,the menu can popup,but not immediately,it seems a little latency. this is my code, is anything wrong?
My Qt version is 5.15, my system is Windows 10.
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.12
Window {
visible: true
width: 450
height: 350
title: qsTr("ListView")
property bool refreshFlag: false
Rectangle {
id: rightview
width: 60
height: 300
x: 100
color: "#EEEEEE"
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton | Qt.LeftButton
onClicked: {
console.log(width)
if (mouse.button === Qt.RightButton)
contextMenus.popup()
}
Menu {
id: contextMenus
MenuItem { text: "open" }
MenuItem { text: "save " }
MenuItem { text: "else..." }
}
}
Text {
font.pointSize: 12
text: "content"
}
}
}
this is my screenshot
A couple of issues with your program snippet:
Don't mix QtQuick.Controls 1.x with QtQuick.Controls 2.x
Recommend you update all your references to versions to 2.15
Do not declare Menu inside MouseArea, it doesn't make sense
The MouseArea can be optimized to only accept the RightButton
Declare the Menu at the "top level"
Here's a cleanup of your code:
import QtQuick 2.15
import QtQuick.Controls 2.15
Page {
anchors.fill: parent
Rectangle {
x: 100
width: 60
height: 300
color: "#EEEEEE"
Text {
font.pointSize: 12
text: "content"
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: contextMenus.popup()
}
}
Menu {
id: contextMenus
MenuItem { text: "open" }
MenuItem { text: "save " }
MenuItem { text: "else..." }
}
}
You can Try it Online!
There appears to be no performance issue when I run the above snippet using qmlonline. I don't think the code is an issue. I think we need to get an understanding of:
Your version of Qt
Your platform (i.e. OS, hardware, etc)

Why does my SwipeView page not change when I change the Tab in the TabBar in QML?

So, I'm trying to create a traditional look for my QML application which simply consists of a TabBar and a SwipeView. There's also another component which essentially boils down to a button click which should result in a new tab in the TabBar and a new page in the SwipeView. This works, except that when I click on the previous tab (there's a static tab and page when the app starts up), the page in the view doesn't change.
Here's my QML file -
import QtQuick 2.12
import QtQuick.Layouts 1.3
import QtGraphicalEffects 1.12
import QtQuick.Controls 2.13
ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: true
Component {
id: tabButton
TabButton {
width: implicitWidth
}
}
Component {
id: resultListView
Rectangle {
anchors.fill: parent
color: "green"
}
}
SwipeView {
id: tabBarLayout
Layout.fillHeight: true
Layout.fillWidth: true
interactive: false
currentIndex: 0
LogArea {
id: logArea
}
}
TabBar {
id: tabBar
currentIndex: tabBarLayout.currentIndex
Layout.fillWidth: true
font.capitalization: Font.MixedCase
TabButton {
text: qsTr("log")
width: implicitWidth
}
Connections {
target: qmlBridge
onLoadResultTab: {
tabBar.addItem(tabButton.createObject(tabBar, {text: qsTr("search - " + term)}))
tabBarLayout.addItem(resultListView.createObject())
tabBarLayout.incrementCurrentIndex()
console.log("Added new item...")
}
}
}
}
The onLoadResultTab signal is invoked when the button is clicked. As you can see, I'm adding a new TabButton and incrementing the current index and then creating another component which is just a simple Rectangle for now. Now, when I click on the "log" button, the SwipeView doesn't change its page to the one corresponding to the log tab. Could anyone point out what's the issue here?

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 get parent button from ButtonStyle without using id?

I created a component (SidebarMenuButton) that is used in the main qml file multiple times. The button has styles that should be inherited by all it's 'instances'. Here is the SidebarMenuButton.qml:
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
Button {
width: buttonNewMessage.width
height: buttonNewMessage.height
anchors {
horizontalCenter: parent.horizontalCenter
topMargin: 5
}
style: ButtonStyle {
background: Rectangle {
color: 'transparent'
}
label: Text {
text: parent.text // undefined here
color: 'white'
font.family: 'Helvetica'
font.pixelSize: 12
font.bold: true
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
}
}
And a part of my main qml file:
import QtQuick 2.3
import QtQuick.Window 2.1
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
Window {
id: main
title: 'Messenger'
width: 1024
height: 768
minimumWidth: 800
minimumHeight: 600
RowLayout {
id: layout
anchors.fill: parent
spacing: 0
Rectangle {
id: sidebar
color: '#3C3E55'
Layout.fillHeight: true
Layout.preferredWidth: 200
ButtonCompanyName {
id: buttonCompanyName
}
ButtonNewMessage {
id: buttonNewMessage
}
SidebarMenuButton {
id: buttonInbox
text: 'Inbox (1)'
anchors.top: buttonNewMessage.bottom
}
SidebarMenuButton {
id: buttonSentMessages
text: 'Sent messages'
anchors.top: buttonInbox.bottom
}
SidebarMenuButton {
id: buttonStarred
text: 'Starred'
anchors.top: buttonSentMessages.bottom
}
}
I commented the line with error. parent there doesn't refer to button so the text in all buttons is empty. I need to access parent button from there and get it's text property. The component has no id cause it's used multiple times and ids are assigned in the main qml file. So the question is: how can I get that button text without id?
There are two ways to set text in your case.
1)The Button for which you are applying the style is available as control property in ButtonStyle class. You can set the the text as text:control.text
Reference:control property(ButtonStyle)
2)You can give an id to the Button in SidebarMenuButton type and access its textproperty.
Button
{
id:button
.
.
.
text: button.text
}
You can assign an id inside your component file that would not conflict with the id you use when you instantiate the component somewhere else. I use the same value for the id of most of my QML components: container so that I can easily reference properties from the root of the item.
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
Button {
id: container
style: ButtonStyle {
background: Rectangle {
color: 'transparent'
}
label: Text {
text: container.text
}
}
}
Then when you instantiate this component in another file you set whichever id you want and it would still work

How to use QtQuick.Window element in Qt5 and QML?

I recently installed the Qt5 RC2 for Mac OS X and started developing some QML applications. After looking at the new elements, I especially wanted to try the Window and Screen Element. (http://qt-project.org/doc/qt-5.0/qtquick/qmlmodule-qtquick-window2-qtquick-window-2.html)
So I set the imports at the top of the file like this:
import QtQuick 2.0
import QtQuick.Window 2.0
The import is found, but I can use neither Window nor Screen. Everytime I type Screen or Window an error appears which says "Unknown component (M300)"
Has anyone an idea what the problem is?
Sometimes QtCreator doesn't recognize some types/properties, mainly the ones that were not present in Qt4.x, but that doesn't mean you can't use them, so yes, 'Window' is unknown just like properties 'antialiasing', 'fontSizeMode' or 'active' are, but you can use them, here is an example of use for QtQuick.Window 2.0 :
import QtQuick 2.0
import QtQuick.Window 2.0
Window {
id: win1;
width: 320;
height: 240;
visible: true;
color: "yellow";
title: "First Window";
Text {
anchors.centerIn: parent;
text: "First Window";
Text {
id: statusText;
text: "second window is " + (win2.visible ? "visible" : "invisible");
anchors.top: parent.bottom;
anchors.horizontalCenter: parent.horizontalCenter;
}
}
MouseArea {
anchors.fill: parent;
onClicked: { win2.visible = !win2.visible; }
}
Window {
id: win2;
width: win1.width;
height: win1.height;
x: win1.x + win1.width;
y: win1.y;
color: "green";
title: "Second Window";
Rectangle {
anchors.fill: parent
anchors.margins: 10
Text {
anchors.centerIn: parent
text: "Second Window"
}
}
}
}
You just need to have a Window item as root object, and you can embed other Window items into it.

Resources