QML : Link MenuBar and ToolBar actions - c++

I'm quite new to Qt Quick (and Qt in general), and i'd like to have an advice on "good way" to do this.
In an application, if I have a menubar and toolbar that have common actions, is there a way to link the buttons from menubar and buttons from toolbar ?
For instance, if I have a "save" function. This action is avaible through menubar and toolbar. How can I mutualise this action ?
At the moment, the best way i've found is to create a function "save" that is called by both buttons.

I've actually found a "good practice" for this problem on QML example : use Action items.
For instance :
FileDialog {
id: openDialog
onAccepted: myData.source= fileUrl
}
Action {
id: openFile
iconSource: "images/fileopen.png"
text: "Open"
onTriggered: openDialog.open()
}
menuBar: MenuBar {
Menu {
MenuItem { action : openFile }
// ....
toolBar : ToolBar {
ToolButton { action:openFile}

Related

Qt/QML: WebEngineView and ScrollView

I have desktop app in which I have a ScrollView that contains a ListView, in which the delegates each contain multiple widgets, including a WebEngineView:
ScrollView
{
id: myScrollView
anchors.fill: parent;
ListView
{
id: myListView
delegate: Item
{
Rectangle
{
Text ...
Text ...
// other stuff
WebEngineView
{
id: myWebEngineView
Component.onCompleted:
{
loadHtml(model.modelData.someHTMLData);
}
}
}
}
}
}
The problem I am having is with scrolling. On Mac, if I use the touchpad to scroll, the ListView only scrolls if the mouse is hovered over one of the non-WebEngineView widgets.
I suspect the WebEngineView widgets are trapping the mouse messages but I cannot find a way stop this from happening. How can I do this?
One thing that I know about Qt Quick is that it has input focus.
According to this, you can play with FocusScopes and focus property.
For example set ListView's focus to true, lay delegate into FocusScope with focus: false. Or set WebEngineView's focus to false.
Hope this helps =)

How to set initial focus to a button in a viewController from a UITabBarController?

I have a basic application with a UITabBarController which contains 2 UIViewControllers.
The first ViewController has a UIButton in it.
I'm trying to get the tabBar menu hidden and the button focused when the app launches.
I set the tabBar as hidden, and it does not show on launch as expected. Unfortunately, the button doesn't have the focus.
From what I understand from Apple doc, the "focus chain" engine will set focus on the first visible and focusable item in the window hierarchy.
Can anyone help me on this ?
Thank you.
Solution 1.
I think what you can do :
1.Subclass or Customize TabBarController and set
set first launch = true in viewdidload of tabController
> override weak var preferredFocusedView: UIView? { if
> (self.firstLaunch) {
> self.firstLaunch = false;
> return self.selectedViewController!.preferredFocusedView; } else {
> let view = super.preferredFocusedView
> return view; }
Hope it helps.It worked for me though
Your focus engine takes the rootView controller as TabBarController and then asks for preferred focus view which is returned as UITabBarItem we need to unfocus that subclassing the class and returning canBecomeFocus to NO.
if you want to change the focus of the element in the firtsViewController then you can overrirde func preferredFocusView and reutrn the view you want to be focussed else preferredFocusView
Solution 2. Just set the root View controller as the HomeViewController without the TabBarController and embed the TabBarController from the second page. This is because anyways you don't need to use TabBar on the first page why need to take care of its focus.
TabBar is set to hidden if you hide from the AppDelegate or the view which is loaded but it has the focus.

Qt Creator: Button Click Signal to make a window pop- up

I’m using Qt Creator's Qt Quick and as suggested in the tutorial I made different .qml for every button.
I want when the button is clicked to make a window pop- up. What should I write after
onClicked:
in the mouseArea.
Also how to make a second window (the pop- up one), what should I add to the project so I can design it like the main one?
I read that I have to make a class that inherits with QWidget but I need a bit more information.
A short example would be great.
as suggested in the tutorial I made different .qml for every button
Surely you mean "for every button type"!?
To launch a second window:
// Main.qml
Window {
id: win
width: 640
height: 480
Button {
text: qsTr( "Open" )
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
onClicked: {
var factory = Qt.createComponent( "Popup.qml" );
factory.createObject( win );
}
}
}
// Popup.qml
Window {
height: 240
width: 320
title: qsTr( "Popup" )
visible: true
Text {
text: qsTr( "Hello" )
anchors.centerIn: parent
}
}
I read that I have to make a class that inherits with QWidget
Do not mix QML and the Qt Widgets module unless you are extending/converting a legacy system, QML has been designed to replace Qt Widgets (at some point).

Binding Checkbox 'checked' property with a C++ object Q_PROPERTY

I'm learning QtQuick and I'm playing with data binding between C++ classes and QML properties.
In my C++ object Model, I have two properties :
Q_PROPERTY(QString name READ getName WRITE setName NOTIFY nameChanged)
Q_PROPERTY(bool status READ getStatus WRITE setStatus NOTIFY statusChanged)
And in my .qml file :
TextEdit {
placeholderText: "Enter your name"
text: user.name
}
Checkbox {
checked: user.status
}
When I change the user name with setName from my C++ code, it is automatically reflected in the view.
When I check/uncheck the checkbox, or when I call setStatus() from my C++ code, nothing happens. It seems the property checked of checkboxes haven't the same behavior as TextEdit components.
I don't want to bind my properties in a declarative way. Doesn't Qt Quick support property binding ?
Thank you for your help.
As leemes points out, user clicking the check box breaks the binding you've created. So, don't create the binding, but instead connect to the change signal directly to handle the "get" case. Use "onClicked" to handle the "set" case. This solution requires you also initialize in Component.onCompleted(). For example...
CheckBox {
id: myCheck
onClicked: user.status = checked
Component.onCompleted: checked = user.status
Connections {
target: user
onStatusChanged: myCheck.checked = user.status
}
}
A way around this is to restore the binding (that gets removed by the user clicking the checkbox) in onClicked, by something like:
CheckBox {
checked: user.status
onClicked: {
user.status = checked;
checked = Qt.binding(function () { // restore the binding
return user.status;
});
}
}
This avoids problems if you don't have the possibility to access your model at the time Component.onCompleted is invoked.
I find it more natural to make checkbox only emit signal on click, not change its state:
// MyCheckBox.qml
CheckBox {
id: control
property bool changeOnClick: true // or just emit clicked()
MouseArea {
anchors.fill: parent
enabled: !control.changeOnClick
onClicked: control.clicked();
}
}
Then you can bind it once and request change of the source on click:
MyCheckBox {
changeOnClick: false
checked: user.state
onClicked: {
user.state = !user.state;
}
}

Option style (Dropdown, RadioGroup, etc) in QML or C++ (Cascades)

I'm trying to set a custom style to a group of options belonging to a dropdown or a Radio Group. I'm searching all over and it seems impossible. At least I would like to decrease the size of the letters in the text of each option because is too big! and crashes my UI.
Here's and example of what I need:
RadioGroup {
id: groupOrigin
objectName: "groupOrigin"
Option{
text: "text to display"
//This text default style is what I'm trying to change. Please help!.
}
}
thanks!
for Radio group you can achieve this using custom implementation. Take a label and place it after the radio group did not provide text inside the options tag. So whatever style you want to apply can be done using label.
On label you can set the font size, color and other style parameter you want to apply.
Please check the source code below for this custom radio button. I did this in the QML you can achieve same in C++.
// The Component title.
Label {
id: titleLabel
text: ""
textStyle {
base: SystemDefaults.TextStyles.SmallText
alignment: TextAlignment.Center
}
layoutProperties: StackLayoutProperties {
horizontalAlignment: HorizontalAlignment.Fill
}
}
// The radio group presenting the different curves.
RadioGroup {
id: radioGroup
Option {
text: "Height"
}
}