What is button property "tooltip" used for? - qt

I'm writing a test application to try out what QML has to offer. I have created a simple button and tried to create a tooltip on mouse hover event. I found several solutions already how to make that happen (example) and it is not a problem.
In the documentation, however, I have encountered a button property called tooltip. Now I assumed if a built-in component has such a property then creation of tooltip is automated. Apparently that is not the case, since defining tooltip property did not change anything.
The question is what is this property actually used for?
Button {
id: myButton
x: 10
y: 10
text: "Click me"
tooltip: "Some tooltip"
}

Showing of tooltip requires receiving of mouse hover events and this is possible only if your button is not overlapped with some another MouseArea with hoverEnabled property equal to true. Following example shows tooltip fine on OS X and Qt 5.2.1:
import QtQuick 2.0
import QtQuick.Controls 1.1
Rectangle {
width: 360
height: 360
Text {
anchors.centerIn: parent
text: "Hello World"
}
Button {
id: myButton
x: 10
y: 10
text: "Click me"
tooltip: "Some tooltip"
}
}

Related

Modify hover behaviour for a simple button for QML in Qt 6.1.2

I just made the change from Qt 5.12.3 to 6.1.2. Having done this I went ahead and compiled a very simple QML App:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.0
ApplicationWindow {
id: mainWindow
visible: true
//visibility: Window.Maximized
width: 1000
height: 800
title: qsTr("Hello World")
Button {
id: myTestButton
width: 100
height: 50
text: "Click Me!"
anchors.centerIn: parent
//hoverEnabled: false
onClicked: {
console.log("Button Was clicked")
}
}
}
When I hover over the button now, it slowñy gets covered by a slight blue tranparent overlay while the mouse is over the button. I can disable this by setting hoverEnabled to false, but I much rather change it to something that I can use. How can change the color of this hover overlay?
Within Button {} try adding
flat: true
The default value is false and highlights the background of the button when hovered over.
This seemed like something that was imposed by the default style used on Windows (this was changed in Qt6). Probably from https://github.com/qt/qtdeclarative/blob/d6961c09de36e15c57f29109edf5fbfef53ef4d4/src/quickcontrols2/windows/Button.qml#L19 (but I'm not completely certain).
I couldn't find any obvious way of customizing this, therefore I switched the style QML was using (in my case globally, in C++, before loading anything):
QQuickStyle::setStyle("Fusion");
(Other ways of selecting styles exist)
Obviously this does change the overall appearance of the application, but that may not matter if you're heavily customizing all your components.
If you do want to customize the effect instead of disabling it, then you're probably still better switching styles, and then customizing your background item as proposed in one of the other answers. Otherwise it'll almost certainly fight with whatever customization you add in background. The Qt documentation discourages customization of the Windows style and advises you to base a customized control on "a style that's available on all platforms".
This is an example with the help of qt documentation:
Button {
id: control
text: "First"
Layout.fillWidth: true
hoverEnabled: true
background: Rectangle {
implicitWidth: 100
implicitHeight: 40
opacity: enabled ? 1 : 0.3
border.color: control.down ? "#ff0000" : (control.hovered ? "#0000ff" : "#00ff00")
border.width: 1
radius: 2
}
}

Qt5-QML: How to handle change of color and text of a button after click event

I am writing a small application that is working as follows:
1) I launch the application and I select a robot to which I will connect. See print screen below of the small app:
2) That will lead me to another page where I can actually choose the robot to connect to as shown in the print screen below:
3) Finally after selecting the robot the application brings me back to the initial screen that will show me an additional Button showing the chosen robot.
The problem: I have is that after I choose the robot and I am back to the initial screen and I push the button the color of the button should turn into a (for example) green color and changing the text into (for example) Connecting...
The code I am using is the following for which I am only putting the related part:
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtQuick.Controls.Styles 1.4
Page {
property int dialogId: -1
signal selectDialog()
ColumnLayout {
anchors.fill: parent
spacing: 5
Button {
id: button1
text: "Select Robot"
onClicked: selectDialog()
Layout.fillWidth: true
font.pointSize: 20
}
Button {
id: dialogA
text: "FreddieMercury: Connect";
visible: dialogId === 1
Layout.fillWidth: true
font.pointSize: 20
function buttonClick()
{
console.log("Button "+ dialogA.text +" is clicked!")
}
Rectangle {
id: button
color: "red"
width: 96; height: 24; anchors.centerIn: parent
MouseArea {
id: region
anchors.fill: parent;
onClicked: console.log("clicked()")
onPressed: dialogA.color = "green"
onReleased: dialogA.color = "red"
}
Text {
id: st_text
anchors.centerIn: parent
text: "Connecting..."
font.bold: true
font.pointSize: 20
color: "green"
}
}
}
// Other Buttons
}
}
What I tried so far
I went through this source and also this post which I followed. As you can see from the point 3) I am close to the good functioning but there is clearly something I am not doing right.
Also this was useful and in fact I used the MouseArea option exactly from that post.
However I still don't see the whole color extended into the button.
Finally the text changed after the click event happened I included it in the Button as shown and thought that the property text: "Connecting..." was enough to overwrite the existing text but without success.
Please advise on what I am missing that is keeping me from a full working example.
I think the base issue is that you're trying to use examples for QtQuick Controls 1 with QtQuick Controls 2. They're completely different animals and you cannot style the v2 controls using QtQuick.Controls.Styles.
For customizing Controls 2 styles, like Button, see here. I also find it useful to look at the source code for the included controls (they're in your Qt library install folder inside /qml/QtQuick/Controls2/ directory). Though personally I find needing to re-create a whole new Button (or whatever) just to change a color or font is a bit much, especially if I want it to work across all the included QtQuick Controls2 Styles.
An alternative is to "hack" the properties of the built-in Control styles. This certainly has some drawbacks like if you want to be able to reset the control style back to default bindings, you'd have to save the original bindings and re-create them to reset the style. OTOH it beats creating customized controls for each style. YMMV.
Anyway here's an example of what i think you're looking for. This is based on our previous exercise with the buttons. :) Specifically, I just modified the Page1.qml code and the other 2 files are exactly the same as before. In this page I added buttonClick() handler and the Button::onClicked calls to trigger it from each button (and the button texts of course :).
Page1.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Controls.impl 2.12 // for IconLabel
import QtQuick.Layouts 1.12
Page {
property int dialogId: -1;
signal selectDialog()
function buttonClick(button)
{
button.text = qsTr("Connecting to %1...").arg(button.text);
button.enabled = false; // prevent repeat clicks
// If Button has a background Rectangle object then we can set properties on it.
// note: `instanceof` was added in Qt 5.10
if (button.background && button.background instanceof Rectangle) {
button.background.color = "red"; // override style color
button.background.gradient = null; // some styles use a gradient
button.background.visible = true; // some styles may hide it in some situations
}
// Similar with the label element, IconLabel is used by all included QML styles.
if (button.contentItem && button.contentItem instanceof IconLabel) {
button.contentItem.color = "blue"; // override style color
button.contentItem.font.bold = true;
button.contentItem.font.pointSize = 20;
}
}
ColumnLayout {
anchors.fill: parent
spacing: 5
Button {
id: button1
text: "Select"
onClicked: selectDialog()
Layout.fillWidth: true
}
// These buttons should appear only after the user selects the choices on `Page2`
Button {
id: dialogA
text: "Freddie Mercury"
visible: dialogId === 1
Layout.fillWidth: true
onClicked: buttonClick(this)
}
Button {
id: dialogB
text: "David Gilmour"
visible: dialogId === 2
Layout.fillWidth: true
onClicked: buttonClick(this)
}
Button {
id: dialogC
text: "Mick Jagger"
visible: dialogId === 3
Layout.fillWidth: true
onClicked: buttonClick(this)
}
}
}
If you had a customized Button (like in the Qt docs example) then you could still do basically the same thing in buttonClick() but probably w/out worrying about the if (button.background ...) stuff (since you'd be sure your button has valid background/contentItem Items).
A better implementation of a "default" (Style-specific) Button but with custom colors/text properties would involve a subclass which uses Binding and/or Connections QML elements to control the properties and be able to reset them back to the current QtQuick Style defaults.

Add background and font colour to a button with material design

I am trying to design a login form with a material design on Qt which should look something like this:
However I can't figure out how to add colour to the button in QML and change the font colour of the button text. This is what I have got so far:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
Item {
property alias login: login
Pane {
id: pane
x: 144
y: 117
width: 353
height: 246
clip: false
font.strikeout: false
background: Rectangle {
color: "#ffffff"
}
ColumnLayout {
id: columnLayout
x: 139
y: -158
anchors.fill: parent
TextField {
id: username
Layout.fillWidth: true
placeholderText: qsTr("Username")
}
TextField {
id: password
Layout.fillWidth: true
placeholderText: qsTr("Password")
}
Button {
id: login
text: qsTr("Login")
spacing: -2
font.capitalization: Font.MixedCase
Layout.fillWidth: true
highlighted: false
// background: Rectangle {
// implicitWidth: 100
// implicitHeight: 40
// color: button.down ? "#d6d6d6" : "#f6f6f6"
// border.color: "#26282a"
// border.width: 1
// radius: 4
// }
}
}
}
}
As you can see (in the commented code) I tried to add colour using Rectangle with the background property but this removes the button features like shadow, highlight, darken on click and so on. Is there a simple way to accomplish this?
For reference here is the output of my code:
In order to theme a Material controls, you have to use the Material attached properties
In your case you want to use Material.background :
import QtQuick.Controls.Material 2.2
// ...
Button {
id: login
text: qsTr("Login")
Layout.fillWidth: true
Material.background: Material.Indigo
Material.foreground: "white"
}
Note that buttons should have upercased text, according to the material guidelines.
If you want to have a design that complies with the Google Materials design guidelines, the easiest way, is to use
QtQuick.Controls.Materials
To use them, it is sufficent to use any of the methods described here to activate them in your application. To try it out, I'd reccomend the command line argument. Just start your application with
-style material
If you want to have it fixed in your code, put it in the main.cpp:
QQuickStyle::setStyle("Material");
Note that the -style options is the very same option defined here for widgets and desktop os styles. Despite this quick styles and widget styles are totally different things and you cannot apply the former to the latter and vice versa. Widget
If now you already use the Material-style, but are not contempt with it and desire to change some of the definitions for selected controls, you can import
import QtQuick.Controls.Materials 2.x
where you need to adapt x to the most recent version installed. 0 is the right one for Qt5.7
Then you can alter specific aspects like
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Controls.Material 2.0
ApplicationWindow {
id: mainWindow
width: 800
height: 600
visible: true
Button {
id: login
text: qsTr("LOGIN")
Material.background: Material.Orange // Change the background
}
}
If you don't want to use the Material and only want to change a specific color of the Control you need to understand why it is not that easy to do, without messing it up.
I tried to add colour using Rectangle with the background property but this removes the button features like shadow, highlight, darken on click and so on. Is there a simple way to accomplish this?
You can't just change the color of the background, as there is not the color. There are various colors that are applied for different states. The expression might look like this:
color: (control.down ? 'darkgrey' : 'lightgrey')
So if you change the color to orange like this:
color: 'orange'
you messed up, as now the other state is not considered anymore.
Additionally, of course, you can't change the color of the background like background.color: 'green' from the beginning, as QML does not know about the property background.color. It expects an Item there, which has no color and the Rectangle is only created later. So what you need to do is
Be cautious to not override states
Wait until the property is available
example.qml
Button {
id: login
text: qsTr("LOGIN")
Binding {
target: login
property: "background.color"
value: 'red'
when: !login.pressed // Here comes the state
}
}
You can simply highlight a Button to make the button colorize its background in a style-independent way. The Material style fills the background with the accent color and makes the text light:
Button {
text: qsTr("Login")
highlighted: true
}
A highlighted Button is by far more efficient than a customized button. Customization should be done only if necessary. It is just a visual highlight. There can be multiple highlighted buttons. Highlighting a Button does not affect focus.

QML - Dynamically swap the visibility/opacity between overlapping Text and TextArea

I want to have a widget in QML which has combination of the following behaviors:
1) Multi line edit
2) Auto scroll the content as and when I hit newline. (The content on top of the page keeps going up as and when I enter new content at the bottom)
3) Have a placeholder text functionality.
As far as I know, only Text and TextField are having placeholder text property and only TextArea is having a multi line edit plus auto scroll. But If there is any such widget with all the combinations then, my question “Dynamically swap the visibility/opacity between overlapping Text and TextArea “ would be invalid.
In case there is no such widget (I wonder why), I am thinking to have a rectangle which has both Text and TextArea overlapping and based on the below logic I want to have the visibility/opacity/focus on one of them:
If the Text Area is empty (0 characters), then have the Text in the foreground with focus and with the placeholder text “Enter some text”. But as soon as the user starts typing, the Text should lose the focus, opacity and go to background and the TextArea should gain the focus and come to the foreground and start accepting multi line input. Similarly, when TextArea is in the foreground and is empty (0 characters) and when the user click on any other widget outside my Rectangle, the Text should again gain the focus, come to the foreground and display the placeholder again.
I tried to get inspiration from this code, but failed miserably, it would be helpful if anyone can help me with a few lines of code or give me some pointers on how to solve this.
You can implement placeholderText for TextArea the same way Qt does in TextField. The source can be found here: TextField.qml
When you remove all the comments and properties, you basically have a background and on top of that a MouseArea, the placeholderText Text and a TextInput. Since you need to have the placeholder visually below the TextArea, you must have a transparent background:
PlaceholderTextArea.qml
import QtQuick 2.3
import QtQuick.Controls 1.2
Rectangle {
property alias placeholderText: placeholder.text
id: background
width: 640
height: 480
color: "#c0c0c0"
Text {
id: placeholder
anchors.fill: parent
renderType: Text.NativeRendering
opacity: !textArea.text.length && !textArea.activeFocus ? 1 : 0
}
TextArea {
id: textArea
anchors.fill: parent
backgroundVisible: false
}
}
and use your component:
PlaceholderTextArea {
placeholderText: qsTr("Hello World")
anchors.fill: parent
}
Here's an alternative implementation, that works a bit better for me:
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
Item
{
property alias placeholderText: placeholder.text
property bool __shouldShowPlaceholderText:
!textArea.text.length && !textArea.activeFocus
// This only exists to get at the default TextFieldStyle.placeholderTextColor
// ...maybe there is a better way?
TextField
{
visible: false
style: TextFieldStyle
{
Component.onCompleted: placeholder.textColor = placeholderTextColor
}
}
TextArea
{
id: placeholder
anchors.fill: parent
visible: __shouldShowPlaceholderText
activeFocusOnTab: false
}
TextArea
{
id: textArea
anchors.fill: parent
backgroundVisible: !__shouldShowPlaceholderText
}
}

QtQuick - button onClick event

Background story
So I recently decided that I should try out Qt. I started making a QtQuick Apllication. In my designer view I have one button and a mouse area.
What I want to do:
When I click the button, I want to display a message box with some text (like "Hello World").
My Question
How can I do that ?
Additional info
I tried googling it, i tried following this answer. But still nothing.
I know how to program in .Net (C# and VB), i have some knowage in C/C++, but Qt seems to hard for me
How about this:
import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Dialogs 1.1
Rectangle {
width: 360
height: 360
MessageDialog {
id: msg
title: "Title"
text: "Button pressed"
onAccepted: visible = false
}
Button {
text: "press me"
onClicked: msg.visible = true
}
}
And if you prefer to have the dialog dynamically instantiated with arbitrary properties rather than have it "hardcoded", follow the first snippet from this answer. You can also set properties in createQmlObject() and instead of hiding the dialog just use destroy() to delete it.
You have to use signals and slots in order to trigger an event. You could use a QMessageBox that pops up to display Hello world.

Resources