How do you set the action menu button as selected when it's already on its view? I ave this one view with action menu tabs, then when you tapped one then it'll redirect the user to that view, and I want the button to be displayed as pressed. Where do I set the selected state of the button?
Here's my qml:
import bb.cascades 1.0
Page {
Container {
background: Color.create("#f9f7f2");
layout: StackLayout {}
// Container for holding the title
Container {
horizontalAlignment: HorizontalAlignment.Center
layout: DockLayout {}
ImageView {
horizontalAlignment: HorizontalAlignment.Fill
verticalAlignment: VerticalAlignment.Fill
imageSource: "asset:///images/navigation_bar.png"
}
Container {
horizontalAlignment: HorizontalAlignment.Right
rightPadding: 30
topPadding: 40
layout: DockLayout {}
ImageButton {
id: btnsettings
verticalAlignment: VerticalAlignment.Center
defaultImageSource: "asset:///images/navbar_icon_settings.png"
onClicked: {
// show settings page when the button is clicked
cppObj.onSettingsClicked();
}
}
}
}
Container {
topPadding: 20
leftPadding: 20
rightPadding: 20
bottomPadding: 20
background: Color.create("#F4E9E1");
horizontalAlignment: HorizontalAlignment.Fill
layout: StackLayout {}
Label {
verticalAlignment: VerticalAlignment.Center
horizontalAlignment: HorizontalAlignment.Left
text: cppObj.name
textStyle {
// fontFamily: FontStyle.Default.Myriad
// fontSize: 36
color: Color.create("#60323C")
}
}
}
Container {
verticalAlignment: VerticalAlignment.Center
horizontalAlignment: HorizontalAlignment.Center
layout: DockLayout {}
Divider {}
ScrollView {
scrollViewProperties {
scrollMode: ScrollMode.Vertical
}
/* ImageView {
id: listviewbackground
verticalAlignment: VerticalAlignment.Center
horizontalAlignment: HorizontalAlignment.Center
scalingMethod: ScalingMethod.Fill
imageSource: "asset:///images/list_view_cell.png"
}*/
ListView {
id: lvprojects
dataModel: cppObj.model()
listItemComponents: [
ListItemComponent {
type: "item"
Container {
horizontalAlignment: HorizontalAlignment.Center
layout: DockLayout {}
touchPropagationMode: TouchPropagationMode.Full;
StandardListItem {
title:ListItemData.desc
}
}
}
]
onTriggered: {
var selectedItem = dataModel.data(indexPath);
onClicked: {
// show issue's comment page when the button is clicked
cppObj.onIssueClicked(selectedItem.name);
}
}
}
}
}
}
actions: [
ActionItem {
title: qsTr ("Add Issue")
imageSource: "asset:///images/actionbar_icon_add.png"
ActionBar.placement: ActionBarPlacement.OnBar
onTriggered: {
cppObj.onAddIssuesClicked();
}
},
ActionItem {
title: qsTr ("Issues")
imageSource: "asset:///images/actionbar_icon_issues.png"
ActionBar.placement: ActionBarPlacement.OnBar
onTriggered: {
cppObj.onIssuesClicked();
}
},
ActionItem {
title: qsTr ("Members")
imageSource: "asset:///images/actionbar_icon_members.png"
ActionBar.placement: ActionBarPlacement.OnBar
onTriggered: {
cppObj.onMembersClicked();
}
}
]
}
I guess what you're trying to achieve is to mark a tab as active: void TabbedPane::setActiveTab (bb::cascades::Tab *activeTab)
Related
My custom ComboBox works is correctly, but I do not understand how to up popup with list of element above of combobox.
ComboBox {
id: pointsPositionComboBox
anchors.fill: parent
displayText: qsTr("Position point")
model: map.pointPositionModel
textRole: "name"
delegate: Row {
Rectangle {
id: delegateRect
width: pointsPositionRect.width - removePointRect.width
height: pointsPositionRect.height
color: {
if (!delegateRectMouseArea.containsMouse)
return "#25263C"
else if (delegateRectMouseArea.containsMouse
&& !delegateRectMouseArea.pressed) {
return "#5F8C6D"
} else if (delegateRectMouseArea.containsMouse
&& delegateRectMouseArea.pressed) {
return "#73AB84"
}
}
Text {
text: model.name
color: "white"
width: parent.width - removePointItem.width
font.pixelSize: pointsPositionComboBox.font.pixelSize
anchors.topMargin: pointsPositionRect.height / 3
anchors.left: parent.left
anchors.leftMargin: 5
}
MouseArea {
id: delegateRectMouseArea
anchors.fill: delegateRect
hoverEnabled: true
acceptedButtons: Qt.LeftButton
onClicked: {
if (hasUserMenuProperty.hasUserMenu()
&& !globalUserManager.hasAccessToPrivilege("controlMap"))
return
const latitude = model.position.latitude
const longitude = model.position.longitude
map.center.latitude = latitude
map.center.longitude = longitude
map.zoomLevel = model.zoomLevel
globalMapProperty.bearing = model.bearing
pointsPositionComboBox.popup.close()
}
}
}
Rectangle {
id: removePointRect
width: 30
height: 30
z: pointsPositionComboBox.z + 1
color: {
if (!removePointItemMouseArea.containsMouse)
return "#25263C"
else if (removePointItemMouseArea.containsMouse
&& !removePointItemMouseArea.pressed) {
return "#73A081"
} else if (removePointItemMouseArea.containsMouse
&& removePointItemMouseArea.pressed) {
return "#52785E"
}
}
Image {
id: removePointItem
anchors.centerIn: parent
source: removePointItemMouseArea.containsMouse ? "qrc:/icons/compass/remove_point_en.svg"
: "qrc:/icons/compass/remove_point_dis.svg"
}
MouseArea {
id: removePointItemMouseArea
anchors.fill: removePointRect
hoverEnabled: true
acceptedButtons: Qt.LeftButton
onClicked: {
if (hasUserMenuProperty.hasUserMenu()
&& !globalUserManager.hasAccessToPrivilege("controlMap"))
return
map.pointPositionModel.remove(map.pointPositionModel.index(index, 0))
}
}
}
}
}
Component.onCompleted: {
pointsPositionComboBox.popup.contentItem.implicitHeight = Qt.binding(function () {
// Делаем отображение только 10 элементов (остальные скроллом только)
return Math.min(pointsPositionRect.height * 10,
pointsPositionComboBox.popup.contentItem.contentHeight)
})
}
How to display a list of combo box elements from the top, and not from the bottom as in the photo?
P.s. I set implicitHeight for displaying element of combobox in Component.onCompleted
P.s.2 Now it looks like picture:
I've used the implicitHeight of the Popup to set its y property. Have a look at the source below. The default behavior of the Popup is when ever it fits below it will open up below, if there is not enough space below it will open above the ComboBox. The following code is a tweaked version of the Customizing ComboBox example from the Qt documentation.
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
Window {
width: 400
height: 300
Row {
anchors.centerIn: parent
ComboBox {
id: control
model: ["First", "Second", "Third"]
delegate: ItemDelegate {
width: control.width
contentItem: Text {
text: modelData
color: "#21be2b"
font: control.font
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
}
highlighted: control.highlightedIndex === index
}
indicator: Canvas {
id: canvas
x: control.width - width - control.rightPadding
y: control.topPadding + (control.availableHeight - height) / 2
width: 12
height: 8
contextType: "2d"
Connections {
target: control
function onPressedChanged() { canvas.requestPaint(); }
}
onPaint: {
context.reset();
context.moveTo(0, 0);
context.lineTo(width, 0);
context.lineTo(width / 2, height);
context.closePath();
context.fillStyle = control.pressed ? "#17a81a" : "#21be2b";
context.fill();
}
}
contentItem: Text {
leftPadding: 10
rightPadding: control.indicator.width + control.spacing
text: control.displayText
font: control.font
color: control.pressed ? "#17a81a" : "#21be2b"
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
implicitWidth: 120
implicitHeight: 40
border.color: control.pressed ? "#17a81a" : "#21be2b"
border.width: control.visualFocus ? 2 : 1
radius: 2
}
popup: Popup {
y: myCheckBox.checked ? -implicitHeight + 1 : control.height - 1
width: control.width
implicitHeight: contentItem.implicitHeight
padding: 1
contentItem: ListView {
clip: true
implicitHeight: contentHeight
model: control.popup.visible ? control.delegateModel : null
currentIndex: control.highlightedIndex
ScrollIndicator.vertical: ScrollIndicator { }
}
background: Rectangle {
border.color: "#21be2b"
radius: 2
}
}
}
CheckBox {
id: myCheckBox
text: qsTr("above")
}
}
}
I need to call a C++ class method with parameters from UI after animation of SwipeView ends.
main.ui
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
SwipeView {
id: swipeView
anchors.fill: parent
Page1 {
id: page1
}
Page2{
id: page2
}
}
XOR {
id: xor
onXorEnded: {
//swipeView.setCurrentIndex(0)
}
onQChanged: {
page2.bar.value = xor.getq()
}
}
}
Page1Form.ui.qml
Page1Form {
kpButton.onClicked: {
kpDialog.visible = true
}
xorButton.onClicked: {
swipeView.setCurrentIndex(1)
xor.crypt(file_path.text, key_path.text, out_path.text)
}
fpButton.onClicked:{
fpDialog.visible = true
}
FileDialog {
id: fpDialog
onAccepted: {
file_path.text = fpDialog.fileUrl
}
}
FileDialog {
id: kpDialog
onAccepted: {
key_path.text = kpDialog.fileUrl
}
}
}
It seems like in xorButton.onClicked xoring starting before animation of swipe view ends. How it works now: Imgur
As a workaround you can bind your action to index changing:
xorButton.onClicked: {
swipeView.setCurrentIndex(1)
}
SwipeView {
id: swipeView
onCurrentItemChanged: {
if(currentIndex == 1)
xor.crypt(file_path.text, key_path.text, out_path.text)
}
}
But anyway, that fires not at end of animation.
As another workaround you can use StackView. It has more properties to control the animation. Another advantage of this control is that user cannot swipe it when you don't expect it. In your case an user just can swipe that. One more advantage is that page doesn't take memory when you don't need it.
import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
Window {
visible: true
width: 800
height: 800
StackView {
id: view
anchors.fill: parent
initialItem: page1
onBusyChanged: {
if(!busy && currentItem.objectName == "page2")
currentItem.run();
}
}
Component {
id: page1
Rectangle {
color: "green"
objectName: "page1"
Button {
anchors.centerIn: parent
text: "swipe me"
onClicked:
view.push(page2)
}
}
}
Component {
id: page2
Rectangle {
color: "yellow"
objectName: "page2"
function run() { sign.visible = true; }
Rectangle {
id: sign
anchors.centerIn: parent
width: 100
height: 100
radius: 50
color: "red"
visible: false
}
}
}
}
I have a ListView which has dynamically added Items, and what I kinda want to know is how I could access items for example by index. Specifically, I want to have the color of the item rectangle change when I change the color using the Color Dialog. I guessed it should be maybe possible to first set a variable to the current item before calling the color dialog and then in the onAccepted method change the color of that item using the variable, but I don't know how to achieve anything of this in QML, because I am rather new to QML. Maybe you can offer even a cleaner way to change the color of the item's rectangle when the color dialog was closed (onAccepted). Thx for any help! :)
import QtQuick 2.0
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQuick.Dialogs 1.2
import QtQuick.Controls.Styles 1.4
Rectangle {
id: listViewContainer
width: parent.width/10*9;
height: 50
Behavior on height {
NumberAnimation {
duration: 100;
}
}
gradient: Gradient {
GradientStop {position: 0.0; color: "white" }
GradientStop {position: 1.0; color: "silver" }
}
radius: 5
ColorDialog {
id: colorDialog
title: "Please choose a color"
onAccepted: {
console.log("You chose: " + colorDialog.color)
Qt.quit()
}
onRejected: {
console.log("Canceled")
Qt.quit()
}
}
Component {
id: playerDelegate
Item {
anchors.left: parent.left
anchors.right: parent.right
height: 50
Column {
Text { text: '<b>Name:</b> ' + name }
Row {
MouseArea {
width: 20
height: 20
onClicked: {
colorDialog.visible = true;
playerColor = colorDialog.color;
//open color dialog
}
Rectangle {
radius: 3
anchors.fill: parent
color: playerColor
}
}
}
}
}
}
ListView {
id: playerListView
anchors.fill: parent
model:
ListModel {
id: playerListViewModel;
ListElement {
name: "Bill Smith"
playerColor: "red"
}
}
delegate: playerDelegate
}
Button {
id: addPlayerButton
anchors.top: playerListView.bottom
anchors.left: playerListView.left
anchors.right: playerListView.right
style: ButtonStyle {
label: Text {
text: "Add new player"
horizontalAlignment: Text.Center
}
}
onClicked: {
root.addnewPlayer(playerListView); //dont worry about this method
playerListViewModel.append({name: "Billy", playerColor: "blue"});
listViewContainer.height += 50;
}
}
}
Here is a sure fire way to make a working colorDialog --
in playerDelegate
Component {
id: playerDelegate
Item {
anchors.left: parent.left
anchors.right: parent.right
height: 50
Column {
Text {
text: '<b>Name:</b> ' + name
}
/* Object to store value from color selector */
Item {
id: colorSelector
property color color: "#000000"
onColorChanged: { playerColor = color; }
}
/* box to display color */
Rectangle {
//Layout.fillWidth: true
height: 120
width: 120
anchors.left: button.right
//Layout.alignment: Qt.AlignHCenter
color: colorSelector.color
border.width: 1
border.color: "#000000"
}
/* button to open dialog -- can be mousearea or other clickable object */
Button {
id: button
text: "Browse..."
onClicked: {
colorDialog.color = colorSelector.color
colorDialog.open()
}
}
/* actual color dialog for this delegate */
ColorDialog {
id: colorDialog
modality: Qt.ApplicationModal
title: "Please choose a color"
onAccepted: colorSelector.color = currentColor
}
}
}
}
I want to place the submit button below the colored box. What should I do to fix the layout?
Whenever I adjust the topPadding the whole covered box adjusts not the submit button
import bb.cascades 1.0
Page {
Container {
background: Color.create("#f9f7f2");
layout: StackLayout {}
// Container for holding the title
Container {
horizontalAlignment: HorizontalAlignment.Center
layout: DockLayout {}
ImageView {
horizontalAlignment: HorizontalAlignment.Fill
verticalAlignment: VerticalAlignment.Fill
imageSource: "asset:///images/navigation_bar.png"
}
Container {
horizontalAlignment: HorizontalAlignment.Right
rightPadding: 30
topPadding: 40
layout: DockLayout {}
ImageButton {
id: btnsettings
verticalAlignment: VerticalAlignment.Center
defaultImageSource: "asset:///images/navbar_icon_settings.png"
onClicked: {
// show settings page when the button is clicked
cppObj.onSettingsClicked();
}
}
}
}
Container {
topPadding: 20
leftPadding: 20
rightPadding: 20
bottomPadding: 20
background: Color.create("#F4E9E1");
horizontalAlignment: HorizontalAlignment.Fill
layout: StackLayout {}
Label {
verticalAlignment: VerticalAlignment.Center
horizontalAlignment: HorizontalAlignment.Left
text: "Add Projects"
textStyle {
// fontFamily: FontStyle.Default.Myriad
// fontSize: 36
color: Color.create("#60323C")
}
}
}
ScrollView {
scrollViewProperties {
scrollMode: ScrollMode.Vertical
}
Container {
verticalAlignment: VerticalAlignment.Center
horizontalAlignment: HorizontalAlignment.Center
Divider {}
Container {
rightPadding: 30
leftPadding: rightPadding
bottomPadding: 40
topPadding: 20
verticalAlignment: VerticalAlignment.Bottom
layout: DockLayout {}
ImageView {
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
topMargin: 40
imageSource: "asset:///images/create_project_frame.png"
}
Container {
horizontalAlignment: HorizontalAlignment.Center
leftPadding: 70
rightPadding: 70
topPadding: 60
Label {
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
text: qsTr("Create a Project")
}
}
Container {
leftPadding: 70
rightPadding: 70
topPadding: 150
TextField {
id: tfMemberName
input.submitKey: SubmitKey.Next
topPadding: 50
hintText: qsTr("project name")
}
}
Container {
rightPadding: 30
leftPadding: rightPadding
bottomPadding: 20
verticalAlignment: VerticalAlignment.Bottom
layout: DockLayout {}
ImageView {
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
topMargin: 40
imageSource: "asset:///images/add_member_frame.png"
}
Container {
horizontalAlignment: HorizontalAlignment.Center
leftPadding: 70
rightPadding: 70
topPadding: 60
Label {
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
text: qsTr("Add a Member")
}
}
Container {
leftPadding: 70
rightPadding: 70
topPadding: 150
TextField {
id: tfEmail
input.submitKey: SubmitKey.Next
topPadding: 40
hintText: qsTr("email address")
}
}
Container {
horizontalAlignment: HorizontalAlignment.Left
verticalAlignment: VerticalAlignment.Center
topPadding: 250
leftPadding: 180
layout: DockLayout {}
ImageButton {
id: btnaddmore
defaultImageSource: "asset:///images/button_add.png"
onClicked: {
controller.showProjectsPage(); /*var projectsPage = page.createObject();
navPane.push(projectsPage);*/
}
}
}
Container {
horizontalAlignment: HorizontalAlignment.Right
rightPadding: 250
topPadding: 310
Label {
horizontalAlignment: HorizontalAlignment.Right
text: qsTr("add more")
}
}
}
}
}
ImageButton {
id: btnsubmit
horizontalAlignment: HorizontalAlignment.Center
defaultImageSource: "asset:///images/button_submit.png"
}
}
}
/*actions: [
ActionItem {
title: qsTr ("Add Project")
imageSource: "asset:///images/actionbar_icon_add.png"
ActionBar.placement: ActionBarPlacement.OnBar
/*onTriggered: {
_projects.addProjects()
navigationPane.push(addProjects.createObject())
}
}
]*/
}
I want to achieve this look
If I got you right, this code
import bb.cascades 1.0
Page {
// [0]
Container {
background: Color.Gray
topPadding: 40
leftPadding: 20
rightPadding: leftPadding
bottomPadding: topPadding
layout: StackLayout {
}
// [1]
Container {
leftPadding: 40
rightPadding: leftPadding
background: Color.Red
maxHeight: 350
// [2]
Container {
layoutProperties: StackLayoutProperties {
spaceQuota: 1.5
}
Label {
horizontalAlignment: HorizontalAlignment.Center
text: "Add a Member"
}
TextField {
horizontalAlignment: HorizontalAlignment.Center
hintText: "email address"
}
} // [2]
Container {
layoutProperties: StackLayoutProperties {
spaceQuota: 1
}
horizontalAlignment: HorizontalAlignment.Center
Container {
layout: StackLayout {
orientation: LayoutOrientation.LeftToRight
}
Button {
text: "+"
}
Label {
verticalAlignment: VerticalAlignment.Center
text: "add more"
}
}
}
} //[1]
Button {
horizontalAlignment: HorizontalAlignment.Center
text: "Button submit"
}
} // [0]
}
will give you the following layout:
Simply replace Buttons with your custom ImageButtons
I want to call C++ function from Cascade QML
this is CalcolatorQML.cpp
// Default empty project template
#include "CalcolatorQML.hpp"
#include <bb/cascades/Application>
#include <bb/cascades/QmlDocument>
#include <bb/cascades/AbstractPane>
#include <QDebug>
using namespace bb::cascades;
CalcolatorQML::CalcolatorQML(bb::cascades::Application *app)
: QObject(app)
{
// create scene document from main.qml asset
// set parent to created document to ensure it exists for the whole application lifetime
QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);
// create root object for the UI
AbstractPane *root = qml->createRootObject<AbstractPane>();
// set created root object as a scene
app->setScene(root);
//Container *container = root->findChild<Container*>("myContainer");
}
void CalcolatorQML::injectContainer(){
qDebug("NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN");
}
and I declare the function as Q_INVOKABLE void injectContainer();
this is CalcolatorQML.hpp
// Default empty project template
#ifndef CalcolatorQML_HPP_
#define CalcolatorQML_HPP_
#include <QObject>
namespace bb { namespace cascades { class Application; }}
/*!
* #brief Application pane object
*
*Use this object to create and init app UI, to create context objects, to register the new meta types etc.
*/
class CalcolatorQML : public QObject
{
Q_OBJECT
public:
CalcolatorQML(bb::cascades::Application *app);
virtual ~CalcolatorQML() {}
Q_INVOKABLE void injectContainer();
};
#endif /* CalcolatorQML_HPP_ */
and this is my main.qml, you can see in b1 click this statement injection.injectContainer1();
import bb.cascades 1.0
Page {
content: Container {
Container {
layout: StackLayout {
}
TextField {
id: textFieldId
}
Container {
layout: StackLayout {
orientation: LayoutOrientation.LeftToRight
}
verticalAlignment: VerticalAlignment.Center
horizontalAlignment: HorizontalAlignment.Center
Button {
id: b1
text: "1"
onClicked: {
injection.injectContainer();
}
}
Button {
id: b2
text: "2"
}
Button {
id: b3
text: "3"
}
}
Container {
layout: StackLayout {
orientation: LayoutOrientation.LeftToRight
}
verticalAlignment: VerticalAlignment.Center
horizontalAlignment: HorizontalAlignment.Center
Button {
id: b4
text: "4"
}
Button {
id: b5
text: "5"
}
Button {
id: b6
text: "6"
}
}
Container {
layout: StackLayout {
orientation: LayoutOrientation.LeftToRight
}
verticalAlignment: VerticalAlignment.Center
horizontalAlignment: HorizontalAlignment.Center
Button {
id: b7
text: "7"
}
Button {
id: b8
text: "8"
}
Button {
id: b9
text: "9"
}
}
Container {
layout: StackLayout {
orientation: LayoutOrientation.LeftToRight
}
verticalAlignment: VerticalAlignment.Center
horizontalAlignment: HorizontalAlignment.Center
Button {
id: b0
text: "0"
}
}
Container {
layout: StackLayout {
orientation: LayoutOrientation.LeftToRight
}
verticalAlignment: VerticalAlignment.Center
horizontalAlignment: HorizontalAlignment.Center
Button {
id: bPlus
text: "+"
}
Button {
id: bMult
text: "*"
}
Button {
id: bEqual
text: "="
}
Button {
id: bDivide
text: "/"
}
Button {
id: bMinus
text: "-"
}
}
}
}
}// end of Page
My problem is the function injectContainer not invoked
Thanks
In CalcolatorQML.cpp, before the line:
AbstractPane *root = qml->createRootObject<AbstractPane>();
add:
qml->setContextProperty("app", this);
Then within onClicked in your QML, try:
app.injectContainer();
try this one
AbstractPane *root = qml->createRootObject<AbstractPane>();
qml->setContextProperty("root", this);
In the Qml onClick write
root.injectContainer();