How I can use tooltip for QML component.



  • Hi everyone!

    How I can use tooltip for all QtQuick Components. As I know I can use tooltip only for 'Button'. How I can add a tooltip for Label?

    Thanks for the any help.


  • Moderators

    hi,

    I didn't try it myself yet, but AFAIK that should be possible.

    Did you try to use it like this?
    @
    Label {
    id: lab
    anchors.centerIn: parent
    width: 100
    height: 50

         ToolTip {
             id: toolTip
             text: "ToolTip"
             target: lab
             visible: mouseArea.pressed
         }
    
         MouseArea {
             id: mouseArea
             anchors.fill: parent
         }
     }
    

    @



  • Hi,

    Yes, I have tried this but in Qt 5.3.0 (beta) this component doesn't supported. When I tried it I've received this error: 'ToolTip is not a type'


  • Moderators

    I tested it myself on Qt 5.2.1.

    I get the same error.

    You can check on "JIRA":https://bugreports.qt-project.org/secure/Dashboard.jspa for a reported bug and a possible work around. In case you cannot find anything reported there yet, please file a bug report.

    Please make in link in JIRA to this post and make a tag here with the bug report number.



  • Hi, just wondering since when is there a ToolTip QML object? I don't see any in the documentation so no wonder you are getting errors!? Or am I missing something here? lol
    http://qt-project.org/doc/qt-5/qmltypes.html#t (no tooltip, also in my latest Qt version 5.2.1 in QtCreator shows nothing just QToolTip widget).


  • Moderators

    @Xander.

    You're right.

    Here is the link
    "QML Tooltip...":http://doc.qt.digia.com/qtquick-components-symbian-1.1/qml-tooltip.html

    After some more investigating seems it is part of Qt Quick Components for symbian / harmattan.

    My mistake, but on the other hand worth having a look at the sources



  • Hi everyone!

    I still can't find the solution for my problem with tooltip and I've posted the bugreport to "JIRA":https://bugreports.qt-project.org/browse/QTBUG-37968.

    If someone found the solution please post it here.

    Thanks for the help!


  • Moderators

    Hi shaw,

    Did you see my previous post?
    Qt quick components are only available for symbian / harmattan on Qt4.
    You can't use them directly with Qt5 .
    On the other hand, looking at the sources can help you implementing your own.



  • [quote author="Eddy" date="1396165453"]Hi shaw,

    Did you see my previous post?
    Qt quick components are only available for symbian / harmattan on Qt4.
    You can't use them directly with Qt5 .
    On the other hand, looking at the sources can help you implementing your own.
    [/quote]

    Thanks for the reply but I can use the QtQuick Components in my Qt projects. You can use it too if you add to your QML files next lines of code:
    @
    import QtQuick 2.2
    import QtQuick.Controls 1.2 //QtQuick Components
    import QtQuick.Dialogs 1.1 //Dialogs
    import QtQuick.Window 2.0 //Windows
    @

    But I can't use ToolTip component because the current version of QtQuick doesn't supported it. And you are right I can use my own component for show tooltip and I done this for now. But I think in future release of Qt will be grade to see this component.


  • Moderators

    bq. But I think in future release of Qt will be great to see this component.

    Yes there was a lot of interesting stuff in there.
    I think others could be interested in your Tooltip solution. Maybe you could post it here or even make a wiki about it? Thanks.



  • [quote author="Eddy" date="1396168836"]bq. But I think in future release of Qt will be great to see this component.

    Yes there was a lot of interesting stuff in there.
    I think others could be interested in your Tooltip solution. Maybe you could post it here or even make a wiki about it? Thanks.[/quote]

    Hi,

    I want to share my implementation of ToolTip component. This varian doesn't apply to the best implementation but I think for the begin of the tooltip this is a nice solution for me. The code of ToolTip component looks like:
    @
    import QtQuick 2.0
    import QtQuick.Controls 1.1
    import QtGraphicalEffects 1.0

    Item {
    id: toolTipRoot
    height: toolTipContainer.height
    visible: false
    clip: false
    z: 999999999

    property alias text: toolTip.text
    property alias backgroundColor: content.color
    property alias textColor: toolTip.color
    property alias font: toolTip.font
    
    function onMouseHover(x, y)
    {
        toolTipRoot.x = x;
        toolTipRoot.y = y + 5;
    }
    
    function onVisibleStatus(flag)
    {
        toolTipRoot.visible = flag;
    }
    
    Component.onCompleted: {
        var newObject = Qt.createQmlObject('import QtQuick 2.0; MouseArea {signal mouserHover(int x, int y); signal showChanged(bool flag); anchors.fill:parent; hoverEnabled: true; onPositionChanged: {mouserHover(mouseX, mouseY)} onEntered: {showChanged(true)} onExited:{showChanged(false)}}',
            toolTipRoot.parent, "mouseItem");
        newObject.mouserHover.connect(onMouseHover);
        newObject.showChanged.connect(onVisibleStatus);
    }
    
    Item {
        id: toolTipContainer
        width: content.width + toolTipShadow.radius
        height: content.height + toolTipShadow.radius
    
        Rectangle {
            id: content
            width: toolTipRoot.width
            height: toolTip.contentHeight + 10
            radius: 10
    
            Text {
                id: toolTip
                anchors {fill: parent; margins: 5}
                wrapMode: Text.WrapAnywhere
            }
        }
    }
    
    DropShadow {
        id: toolTipShadow
        z: toolTipRoot.z
        anchors.fill: source
        cached: true
        horizontalOffset: 4
        verticalOffset: 4
        radius: 8.0
        samples: 16
        color: "#80000000"
        smooth: true
        source: toolTipContainer
    }
    

    }
    @

    The code to use it looks like:
    @
    ToolTip {
    id: tooltip
    width: 300 //default width is 150px. and height is calculate automatically using the text size.
    backgroundColor: "yellow" //set the background color
    textColor: "blue" //set the text colour
    font.pointSize: 18 //You can use all font settings to set custom font.
    text: "Some <b>text</b> <i>here</i>"; //You can use HTML tags in text.
    }
    @

    But Now I have a problem with z-index of tooltip component. I try to understand why z index in my component is not work correctly. If tooltip will show on the login form where both textfields looks like a group you can see the second textfield is overlaps my tooltip. If you optimised this component please post your version here.

    Thanks for the help!


  • Moderators

    Hi,

    Thanks for sharing.

    When you use your tooltip , do you put it as the last part of your dialog?



  • [quote author="Eddy" date="1396200453"]Hi,

    Thanks for sharing.

    When you use your tooltip , do you put it as the last part of your dialog? [/quote]

    No, I use it as a part of TextField. Here's how looks like the code of my login dialog (full source code):
    @
    import QtQuick 2.2
    import QtQuick.Controls 1.2
    import QtQuick.Dialogs 1.1
    import QtQuick.Window 2.0
    import QtQuick.Layouts 1.1
    import QtGraphicalEffects 1.0
    import com.shav.qtforum 1.0
    import "../"

    Window {
    id: userLoginWindow
    width: 400
    height: 150
    minimumWidth: 400
    maximumWidth: 400
    minimumHeight: 150
    maximumHeight: 150
    modality: Qt.WindowModal
    title: "Login"
    color: "#e8e8e8"

    property var rootApp: null
    
    signal userIsLogIn()
    
    function onUserLoginStatus(status)
    {
        spinner.running = false;
    
        if(status === true)
        {
            userLoginWindow.userIsLogIn();
            userLoginWindow.close();
        }
    }
    
    Component.onCompleted: {
        if(rootApp !== null && rootApp.manager !== null)
        {
            rootApp.manager.userDidLogin.connect(onUserLoginStatus);
        }
    }
    
    Rectangle {
        id: contentView
        anchors {fill: parent; margins: 10}
        color: "transparent"
        clip: true
    
        BusyIndicator {
            id: spinner
            running: false
            anchors {left: parent.left; bottom: parent.bottom}
            width: 30
            height: 30
        }
    
        Rectangle {
            id: userLoginSettings
            width: parent.width
            height: parent.height - buttonsRow.height - 10
            color: "transparent"
            clip: true
    
            Column {
                id: settingsColumn
                width: parent.width
                height: parent.height
                spacing: 5
    
                Row {
                    id: userNameRow
                    width: parent.width
                    height: userNameField.height
                    spacing: 20
    
                    Label {
                        id: userNameLabel
                        width: 100
                        height: parent.height
                        verticalAlignment: Qt.AlignVCenter
                        text: "Username: "
                    }
    
                    TextField {
                        id: userNameField
                        width: parent.width - userNameLabel.width - 20
                        placeholderText: "Your login name here..."
    
                        ToolTip {
                            id: tooltip
                            width: 300
                            backgroundColor: "yellow"
                            textColor: "blue"
                            font.pointSize: 18
                            text: "Some <b>text</b> <i>here</i>";
                        }
                    }
                }
    
                Row {
                    id: userPasswordRow
                    width: parent.width
                    height: userPasswordField.height
                    spacing: 20
    
                    Label {
                        id: userPasswordLabel
                        width: 100
                        height: parent.height
                        verticalAlignment: Qt.AlignVCenter
                        text: "Password: "
                    }
    
                    TextField {
                        id: userPasswordField
                        width: parent.width - userPasswordLabel.width - 20
                        echoMode: TextInput.Password
                        placeholderText: "Your password here..."
                    }
                }
    
                CheckBox {
                    id: savePassword
                    checked: true
                    text: "Keep me logged in for two weeks"
                }
            }
        }
    
        Row {
            id: buttonsRow
            width: btnClose.width + btnRegister.width + btnLogin.width
            height: btnClose.height
            anchors {right: parent.right; top: userLoginSettings.bottom; topMargin: 10}
    
            Button {
                id: btnClose
                text: "Close"
                onClicked: {
                    userLoginWindow.close();
                }
            }
    
            Button {
                id: btnRegister
                text: "Sign Up"
                onClicked: {
                    if(rootApp !== null && rootApp.manager !== null)
                    {
                        rootApp.manager.getRegistrationHiddenFields();
                        userLoginWindow.close();
                    }
                }
            }
    
            Button {
                id: btnLogin
                isDefault: true
                text: "Login"
                onClicked: {
    
                    if(userNameField.text.length > 0 && userPasswordField.text.length > 0)
                    {
                        if(rootApp !== null && rootApp.manager !== null)
                        {
                            spinner.running = true;
                            userLoginWindow.userIsLogIn();
                            rootApp.manager.login(userNameField.text, userPasswordField.text, savePassword.checked);
                        }
                    }
                }
            }
        }
    }
    

    }
    @



  • The z-index only works for sibling items and the parent, not other items deeper in the item tree and siblings of the parent are not affected by it (sadly), that is why it doesn't work in your code.



  • [quote author="Xander84" date="1396201249"]The z-index only works for sibling items and the parent, not other items deeper in the item tree and siblings of the parent are not affected by it (sadly), that is why it doesn't work in your code.[/quote]

    Thanks for the reply! Well I'll try to fix it and upload a new version here tomorrow.



  • I could publish my Tooltip version later, it a little bit different :D



  • It's will be grade!



  • Ok here you go, maybe that is useful for someone.
    I've created a more dynamic tooltip, so usually they are created from JavaScript and not included in the QML layout directly (but can also be done if needed).

    Tooltip.qml:
    @
    import QtQuick 2.2

    Rectangle {
    id: tooltip

    property alias text: tooltipText.text
    property alias textItem: tooltipText
    property int fadeInDelay: 500
    property int fadeOutDelay: 500
    property bool autoHide: true
    property alias autoHideDelay: hideTimer.interval
    property bool destroyOnHide: true
    
    function show() {
        state = "showing"
        if (hideTimer.running) {
            hideTimer.restart()
        }
    }
    
    function hide() {
        if (hideTimer.running) {
            hideTimer.stop()
        }
        state = "hidden"
    }
    
    width: tooltipText.width + 20
    height: tooltipText.height + 10
    color: "#dd000000"
    radius: 6
    opacity: 0
    
    Text {
        id: tooltipText
        anchors.centerIn: parent
        horizontalAlignment: Text.AlignHCenter
        color: "white"
        font.pointSize: 10
        font.bold: true
    }
    
    MouseArea {
        anchors.fill: parent
        onClicked: hide()
    }
    
    Timer {
        id: hideTimer
        interval: 5000
        onTriggered: hide()
    }
    
    states: [
        State {
            name: "showing"
            PropertyChanges { target: tooltip; opacity: 1 }
            onCompleted: {
                if (autoHide) {
                    hideTimer.start()
                }
            }
        },
        State {
            name: "hidden"
            PropertyChanges { target: tooltip; opacity: 0 }
            onCompleted: {
                if (destroyOnHide) {
                    tooltip.destroy()
                }
            }
        }
    ]
    
    transitions: [
        Transition {
            to: "showing"
            NumberAnimation { target: tooltip; property: "opacity"; duration: fadeInDelay }
        },
        Transition {
            to: "hidden"
            NumberAnimation { target: tooltip; property: "opacity"; duration: fadeOutDelay }
        }
    ]
    

    }
    @
    The tooltip has a show and hide function to fade it in and out respectively, by default it will destroy itself after it's hidden (the destroyOnHide property can be set to false if you don't want that).

    Also I have a simple JavaScript file to make it a little easier to create tooltips.

    TooltipCreator.js
    @
    var component = Qt.createComponent("Tooltip.qml");

    function create(text, parent, properties) {
    if (typeof properties === "undefined") {
    properties = {
    anchors: {
    horizontalCenter: parent.horizontalCenter,
    bottom: parent.bottom,
    bottomMargin: parent.height / 8
    }
    };
    }
    properties.text = text;
    var tooltip = component.createObject(parent, properties);
    if (tooltip === null) {
    console.error("error creating tooltip: " + component.errorString());
    } else if (properties.anchors) {
    // manual anchor mapping necessary
    for (var anchor in properties.anchors) {
    tooltip.anchors[anchor] = properties.anchors[anchor];
    }
    }
    return tooltip;
    }
    @
    manual anchor mapping was necessary because it didn't work with Component.createObject properties!? I don't know if that is a bug or an error on my side.

    so I use that TooltipCreator like this for example:
    @
    import "TooltipCreator.js" as TooltipCreator
    ...
    TooltipCreator.create("text on the tooltip", parentItem).show()
    @
    by default it will fade in, stay visible for 5 seconds and than fade out and destroy itself, the user can click on the tooltip to hide it immediately, also it will be anchored at the bottom center of the provided parent Item (see the TooltipCreator.js)

    The 3rd optional argument can be used to specify custom properties for the tooltip, e.g.
    @
    TooltipCreator.create("absolute positioned tooltip"), rootItem, { x: 100, y: 50 }).show()
    @
    or set the properties on the item directly
    @
    var tooltip = TooltipCreator.create(qsTr("Network Error!\nPlease check your network connection\nor try again later."), mainView)
    tooltip.color = "#ddff0000"
    tooltip.textItem.color = "white"
    tooltip.show()
    @

    I hope that helps, it's not perfect but an easy way to show a simple tooltip I think.


  • Moderators

    Thanks for sharing Xander!

    Are you interested in putting it in a wiki page ?

    We can help you with that if you haven't done it yet. Just let us know.

    BTW : thanks for all your contributions on Devnet. We are really happy having you on board!!!



  • [quote author="Eddy" date="1396255883"]
    Are you interested in putting it in a wiki page ?
    [/quote]

    Hi,

    I want to do it but I don't know how I can do it. Could you help me with it. I want to create two version of ToolTip. The one is from the Xander84 and one is a my if you don't mind.

    The new version of my ToolTip looks like:
    @
    import QtQuick 2.0
    import QtQuick.Controls 1.1
    import QtGraphicalEffects 1.0

    Item {
    id: toolTipRoot
    width: toolTip.contentWidth
    height: toolTipContainer.height
    visible: false
    clip: false
    z: 999999999

    property alias text: toolTip.text
    property alias radius: content.radius
    property alias backgroundColor: content.color
    property alias textColor: toolTip.color
    property alias font: toolTip.font
    property var target: null
    
    function onMouseHover(x, y)
    {
        var obj = toolTipRoot.target.mapToItem(null, x, y);
        toolTipRoot.x = obj.x;
        toolTipRoot.y = obj.y;
    }
    
    function onVisibleStatus(flag)
    {
        toolTipRoot.visible = flag;
    }
    
    Component.onCompleted: {
        var itemParent = toolTipRoot.target;
    
        var newObject = Qt.createQmlObject('import QtQuick 2.0; MouseArea {signal mouserHover(int x, int y); signal showChanged(bool flag); anchors.fill:parent; hoverEnabled: true; onPositionChanged: {mouserHover(mouseX, mouseY)} onEntered: {showChanged(true)} onExited:{showChanged(false)}}',
            itemParent, "mouseItem");
        newObject.mouserHover.connect(onMouseHover);
        newObject.showChanged.connect(onVisibleStatus);
    }
    
    Item {
        id: toolTipContainer
        z: toolTipRoot.z + 1
        width: content.width + (2*toolTipShadow.radius)
        height: content.height + (2*toolTipShadow.radius)
    
        Rectangle {
            id: content
            anchors.centerIn: parent
            width: toolTipRoot.width
            height: toolTip.contentHeight + 10
            radius: 3
    
            Text {
                id: toolTip
                anchors {fill: parent; margins: 5}
                wrapMode: Text.WrapAnywhere
            }
        }
    }
    
    DropShadow {
        id: toolTipShadow
        z: toolTipRoot.z + 1
        anchors.fill: source
        cached: true
        horizontalOffset: 4
        verticalOffset: 4
        radius: 8.0
        samples: 16
        color: "#80000000"
        smooth: true
        source: toolTipContainer
    }
    
    Behavior on visible { NumberAnimation { duration: 200 }}
    

    }
    @

    I think the Xander84 version looks more standard. And I think it's will be great if other developers could have a more variants of implementation the tooltip.

    [quote author="Eddy" date="1396255883"]
    BTW : thanks for all your contributions on Devnet. We are really happy having you on board!!![/quote]

    Thanks! I'm happy be with you on board. I'll want to thank you for your hard work on Qt.


  • Moderators

    bq. I want to do it but I don’t know how I can do it. Could you help me with it.

    Have a look at :
    "How to add wiki pages":http://qt-project.org/wiki/WikiHelp

    PS: let Xander decide on his code, since he's the author.



  • Thanks for the link to documentation. I'll check it.

    [quote author="Eddy" date="1396263262"]PS: let Xander decide on his code, since he's the author.[/quote]

    Sure, I'll wait the Xander answer.



  • hey, sure you can post it on the wiki if you like, feel free to use the code.

    maybe I will release some more QML code or apps in the future, actually I just started using QML some month ago and released my first app a week ago, if anybody is interested how it looks on Android: https://play.google.com/store/apps/details?id=ws.aggregator.critiq

    and thanks Eddy, I like to contribute to the community :)



  • Hi,

    I've created the wiki page "QtQuick_ToolTip_Component":http://qt-project.org/wiki/QtQuick_ToolTip_Component So please read this and if you found any mistakes let me know by email.

    Thanks for the help.


  • Moderators

    @shav

    Thanks, i'll have a look at it.


  • Moderators

    @xander

    bq. actually I just started using QML some month ago and released my first app a week ago, if anybody is interested how it looks on Android: https://play.google.com/store/apps/details?id=ws.aggregator.critiq

    looks very nice, cool color choice!



  • I took a different approach and tried creating an actual tooltip window. It works pretty well but there are some flaws. See the code:
    @
    import QtQuick 2.2
    import QtQuick.Window 2.1
    import QtGraphicalEffects 1.0

    // Simple tooltip. There are some flaws:

    // 1. When the tooltip is shown the main window loses focus! There's no way around that currently.
    // 2. Each tooltip has its own window - so if your app has 100 tooltips there will always be
    // 100 (hidden) windows open. Probably not great for performance.
    // 3. You need to provide it with your main window coordinates via mainWindowX and mainWindowY.
    // this is because there is no way to get screen coordinates in QML currently.

    MouseArea {

    hoverEnabled: true

    property alias text: content.text

    // You must alias these to the main window positions.
    property int mainWindowX
    property int mainWindowY

    property int xOffset: 20
    property int yOffset: 5

    onEntered: {
    window.visible = true;
    }

    onExited: {
    window.visible = false;
    }

    Window {
    id: window
    flags: Qt.ToolTip | Qt.FramelessWindowHint | Qt.WA_TranslucentBackground | Qt.WindowDoesNotAcceptFocus
    color: "#00000000"

    width: frame.width + 5 // Space for drop shadow.
    height: frame.height + 5

    x: mapToItem(null, mouseX, mouseY).x + mainWindowX + xOffset
    y: mapToItem(null, mouseX, mouseY).y + mainWindowY + yOffset

    Rectangle {
    id: frame
    width: content.contentWidth + 10 // Padding for text.
    height: content.contentHeight + 10

    color: "#f3f2a5"
    border.width: 1
    border.color: "#bebebe"

    Text {
    id: content
    anchors.centerIn: parent
    }
    }
    DropShadow {
    anchors.fill: frame
    horizontalOffset: 3
    verticalOffset: 3
    radius: 5
    samples: 16
    color: "#80000000"
    source: frame
    cached: true
    fast: true // This looks better for some reason.
    transparentBorder: true // Required. But there's no documentation so I don't know why.
    }
    }
    }
    @
    QML is not mature enough to do this in a bug-free way yet. If you want it to work well you will have to write a C++ component, which is not too difficult. However, I'm reasonably happy with the above code so I'll wait until the trolls write an official implementation I think.



  • Hey guys,
    I was happy enough with the tooltip that came with "Button.qml":http://qt-project.org/doc/qt-5/qml-qtquick-controls-button.html#tooltip-prop, so I extracted the relevant parts from its source code (located in C:\Qt\5.3\msvc2013_64\qml\QtQuick\Controls\Private for me) and used it, instead of a custom solution.

    Here is a minimal example:

    @ import QtQuick 2.2
    import QtQuick.Controls 1.2
    import QtQuick.Controls.Styles 1.1
    import QtQuick.Controls.Private 1.0

    Label {

    property string tooltip: "hello"

    MouseArea {
    id: behavior

    anchors.fill: parent
    hoverEnabled: true

    onExited: Tooltip.hideText()
    onCanceled: Tooltip.hideText()

    Timer {
    interval: 1000
    running: behavior.containsMouse && tooltip.length
    onTriggered: Tooltip.showText(behavior, Qt.point(behavior.mouseX, behavior.mouseY), tooltip)
    }
    }

    }@

    I did like the solutions by shav and Xander, but didn't really want to roll a custom solution unless I really needed to.




Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.