您当前的位置: 首页 > 

龚建波

暂无认证

  • 3浏览

    0关注

    313博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

QML修改Control2中ToolTip附加属性的样式

龚建波 发布时间:2021-03-03 23:25:55 ,浏览量:3

ToolTip是一个较为常用的组件,一般有两种使用方式,直接创建组件或者用附加属性:

        Text{
            text: "..."
            anchors.centerIn: parent

            //附加属性的方式
            ToolTip.text: "..."
            ToolTip.visible: mouse.containsMouse

            //直接创建组件
            ToolTip{
                id: tip
                text: "..."
                visible: !mouse.containsMouse
            }
        }

如果是直接创建组件,那很容易就可以替换为自定义的ToolTip,换个组件名就行了。如果想修改附加属性的样式就有问题了,直接把ToolTip替换为自定义的组件名的话,那么显示出来的效果还是默认的ToolTip 。

我们可以从源码中找到问题的根源(E:\Qt\qt-everywhere-src-5.15.2\qtquickcontrols2\src\quicktemplates2\qquicktooltip.cpp):

QQuickToolTip *QQuickToolTipAttachedPrivate::instance(bool create) const
{
    QQmlEngine *engine = qmlEngine(parent);
    if (!engine)
        return nullptr;

    static const char *name = "_q_QQuickToolTip";

    QQuickToolTip *tip = engine->property(name).value();
    if (!tip && create) {
        // TODO: a cleaner way to create the instance? QQml(Meta)Type?
        QQmlComponent component(engine);
        component.setData("import QtQuick.Controls 2.4; ToolTip { }", QUrl());

        QObject *object = component.create();
        if (object)
            object->setParent(engine);

        tip = qobject_cast(object);
        if (!tip)
            delete object;
        else
            engine->setProperty(name, QVariant::fromValue(object));
    }
    return tip;
}

可以看到,附加属性中这个ToolTip的创建是写死的,并以动态属性的方式保存在engine对象。要改样式只有两种方式:创建同名组件(定义记得带限定符,如T.ToolTip),或者修改源码设置的Property。

如果创建同名组件,那可能有些地方会写漏导致没覆盖掉,所以我认为修改源码设置的Property是更好的方法。

下面是我的测试效果:

GitHub链接:https://github.com/gongjianbo/MyTestCode/tree/master/Qml/TestQml_20210303_ToolTip

完整代码如下(main.cpp+BasicToolTip.qml+main.qml三个文件):

#include 
#include 
#include 
#include 

void updateToolTip(QQmlApplicationEngine *engine);

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);
    updateToolTip(&engine);

    return app.exec();
}

void updateToolTip(QQmlApplicationEngine *engine)
{
    //替换默认的ToolTip附加属性样式
    static const char *name = "_q_QQuickToolTip";
    QQmlComponent *component = new QQmlComponent(engine,QUrl("qrc:/BasicToolTip.qml"),qApp);
    auto create_func = [component,engine]{
        if(component->isError()){
            qWarning() isReady()){
            QObject *object = component->create();
            if (object){
                object->setParent(engine);
                engine->setProperty(name, QVariant::fromValue(object));
            }
        }
    };
    if(component->isLoading()){
        QObject::connect(component,&QQmlComponent::statusChanged,create_func);
    }else{
        create_func();
    }
}
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Controls.impl 2.12
import QtQuick.Templates 2.12 as T

T.ToolTip {
    id: control

    x: parent ? Number.parseInt((parent.width - implicitWidth) / 2) : 0
    y: -implicitHeight - 2

    implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
                            contentWidth + leftPadding + rightPadding)
    implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
                             contentHeight + topPadding + bottomPadding)

    margins: 6
    verticalPadding: 8
    horizontalPadding: 12

    closePolicy: T.Popup.CloseOnEscape | T.Popup.CloseOnPressOutsideParent | T.Popup.CloseOnReleaseOutsideParent

    font{
        family: "Microsoft YaHei"
        pixelSize: 14
    }

    contentItem: Text {
        text: control.text
        font: control.font
        color: "red"
    }

    background: Rectangle {
        border.color: "red"
        color: "white"
        radius: 4
    }
}
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Qml EventLoop")

    Rectangle{
        width: 300
        height: 300
        border.color: "red"
        anchors.centerIn: parent
        Text{
            text: "hover时显示自定义样式"
            anchors.centerIn: parent
            ToolTip.text: "自定义样式"
            ToolTip.visible: mouse.containsMouse
            ToolTip{
                id: tip
                text: "默认样式"
                visible: !mouse.containsMouse
            }
        }
        MouseArea{
            id: mouse
            anchors.fill: parent
            hoverEnabled: true
        }
    }
}

关注
打赏
1655829268
查看更多评论
立即登录/注册

微信扫码登录

0.0993s