如何在QtQuick中访问模型的数据(用于ComboBox中的图标)?

huangapple go评论56阅读模式
英文:

How can I access the model's data in QtQuick (for icons in a ComboBox)

问题

I am trying to extend the QtQuick's ComboBox with icons, and I struggle to access the model's data for the currently selected item. I need to have a textRole, a valueRole and my new iconSourceRole (which defines a qrc: url to a .png file).

Using ComboBox's delegate I can access all the needed data from the model for each row by using model[comboBox.textRole] and model[comboBox.iconSourceRole], but this delegate is not used to render the currently selected item.

contentItem handles this and I cannot find any way to access all the roles from the model from inside there. comboBox.displayText is used for the display text.

My icon ComboBox will be used with different types of models, and they all seem to have a completely different api to get the data. For example Qml's ListModel has a .get() method, which only takes one parameter, Qml's FolderListModel has a .get() method, which needs 2 arguments. And I cannot find any way to access the data from a C++ QAbstractListModel class. Neither .roleNames() nor .itemData() were marked as Q_INVOKABLE, and if I want to use .data(), it seems like I need to know the numeric value of the role instead of the name.

This example code almost works for all cases but not with C++ models and the currently selected item. I am looking for a way to access model from inside contentItem:.

Main.qml

import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Material
import QtQuick.Layouts
import QtQuick.Window
import Qt.labs.folderlistmodel 2.4
import comboboxtests 1.0

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    GridLayout {
        anchors.fill: parent

        columns: 2

        // IconComboBox shall support qml ListModels
        IconComboBox {
            Layout.preferredHeight: 64
            id: listModelComboBox
            textRole: 'theText'
            valueRole: 'theValue'
            iconSourceRole: 'theIconUrl'
            model: ListModel {
                ListElement { theText: 'text0'; theValue: 'value0'; theIconUrl: 'qrc:/comboboxtests/icons/movinghead.png' }
                ListElement { theText: 'text1'; theValue: 'value1'; theIconUrl: 'qrc:/comboboxtests/icons/movinghead.png' }
                ListElement { theText: 'text2'; theValue: 'value2'; theIconUrl: 'qrc:/comboboxtests/icons/nebelmaschine.png' }
                ListElement { theText: 'text3'; theValue: 'value3'; theIconUrl: 'qrc:/comboboxtests/icons/nebelmaschine.png' }
                ListElement { theText: 'text4'; theValue: 'value4'; theIconUrl: 'qrc:/comboboxtests/icons/rgbstrahler.png' }
                ListElement { theText: 'text5'; theValue: 'value5'; theIconUrl: 'qrc:/comboboxtests/icons/rgbstrahler.png' }
            }
        }
        Label {
            text: qsTr('currentValue: ') + listModelComboBox.currentValue
        }

        // IconComboBox shall support qml FolderListModels (to let the user select which icon to use)
        IconComboBox {
            Layout.preferredHeight: 64
            id: folderListModelComboBox
            textRole: "fileBaseName"
            valueRole: "fileBaseName"
            iconSourceRole: "fileUrl"
            model: FolderListModel {
                folder: "qrc:/comboboxtests/icons/"
                showDirs: false

                function getUrlForIcon(name) {
                    let myFolder = folder;
                    if (myFolder.length < 1 || myFolder.charAt(myFolder.length - 1) !== '/') {
                        myFolder = myFolder + '/';
                    }

                    return myFolder + name + ".png";
                }
            }
        }
        Label {
            text: qsTr('currentValue: ') + folderListModelComboBox.currentValue
        }

        // IconComboBox shall support C++ QAbstractListModels (access to our internal database)
        IconComboBox {
            Layout.preferredHeight: 64
            id: cppModelComboBox
            textRole: 'theText'
            valueRole: 'theValue'
            iconSourceRole: 'theIconUrl'
            model: CppDefinedModel {

            }
        }
        Label {
            text: qsTr('currentValue: ') + cppModelComboBox.currentValue
        }

        Item {
            Layout.fillHeight: true
        }
    }
}

IcomComboBox.qml

import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Material
import Qt.labs.folderlistmodel 2.4
import comboboxtests 1.0

ComboBox {
    id: comboBox

    property string iconSourceRole

    delegate: ItemDelegate {
        height: 64
        anchors.left: parent.left
        anchors.right: parent.right
        contentItem: IconChooserDelegateLayout {
            anchors.top: parent.top
            anchors.bottom: parent.bottom
            text: model[comboBox.textRole]
            iconSource: model[comboBox.iconSourceRole]
        }
    }
    contentItem: IconChooserDelegateLayout {
        text: comboBox.displayText
        isInsideMaterialComboBox: true
        iconSource: {
            if (comboBox.currentIndex < 0)
                return '';
            if (!comboBox.model)
                return '';
            if (!comboBox.iconSourceRole)
                return '';

            // FolderListModel has a different API
            if (model instanceof FolderListModel)
                return model.get(comboBox.currentIndex, iconSourceRole);
            // ListModel has another different API
            else if ('get' in model)
            {
                const data = model.get(comboBox.currentIndex);
                console.log(data);
                return data[iconSourceRole];
            }
            // and I dont know how to access C++ models from QML at all
            else if ('roleNames' in model || 'data' in model)
            {
                if (!('roleNames' in model && 'data' in model))
                    throw 'roleNames or data not defined!';

                const roleNames = model.roleNames();
                console.log('roleNames', roleNames);

                const index = model.index(comboBox.currentIndex, 0);
                const data = model.data(index, 99);
                console.log('data', data);

                throw 'getting data from model using roleNames and data is not yet implemented.';
            }
            else
                throw 'unknown model type: ' + typeof model;
        }
    }
}

cppdefinedmodel.h

#pragma once

#include <QAbstractListModel>
#include <qqml.h>

class CppDefinedModel : public QAbstractListModel
{
    Q_OBJECT
    QML_ELEMENT

    enum {
        TextRole = Qt::UserRole,
        ValueRole,
        IconUrlRole
    };

public:
    using QAbstractListModel::QAbstractListModel;

    int rowCount(const QModelIndex &parent) const override
    {
        return 6;
    }
    QVariant data(const QModelIndex &index, int

<details>
<summary>英文:</summary>

I am trying to extend the QtQuick&#39;s ComboBox with icons, and I struggle to access the model&#39;s data for the currently selected item. I need to have a textRole, a valueRole and my new iconSourceRole (which defines a qrc: url to a .png file).

Using ComboBox&#39;s delegate I can access all the needed data from the model for each row by using `model[comboBox.textRole]` and `model[comboBox.iconSourceRole]`, but this delegate is not used to render the currently selected item.

`contentItem` handles this and I cannot find any way to access all the roles from the model from inside there. `comboBox.displayText` is used for the display text.

My icon ComboBox will be used with different types of models, and they all seem to have a completely different api to get the data. For example Qml&#39;s ListModel has a `.get()` method, which only takes one parameter, Qml&#39;s FolderListModel has a `.get()` method, which needs 2 arguments. And I cannot find any way to access the data from a C++ QAbstractListModel class. Neither `.roleNames()` nor `.itemData()` were marked as Q_INVOKABLE, and if I want to use `.data()`, it seems like I need to know the numeric value of the role instead of the name.

This example code almost works for all cases but not with C++ models and the currently selected item. I am looking for a way to access model from inside `contentItem:`.

[![Example application showing comboBoxes with different types of models][1]][1]

Main.qml

import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Material
import QtQuick.Layouts
import QtQuick.Window
import Qt.labs.folderlistmodel 2.4
import comboboxtests 1.0

Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")

GridLayout {
    anchors.fill: parent

    columns: 2

    // IconComboBox shall support qml ListModels
    IconComboBox {
        Layout.preferredHeight: 64
        id: listModelComboBox
        textRole: &#39;theText&#39;
        valueRole: &#39;theValue&#39;
        iconSourceRole: &#39;theIconUrl&#39;
        model: ListModel {
            ListElement { theText: &#39;text0&#39;; theValue: &#39;value0&#39;; theIconUrl: &#39;qrc:/comboboxtests/icons/movinghead.png&#39; }
            ListElement { theText: &#39;text1&#39;; theValue: &#39;value1&#39;; theIconUrl: &#39;qrc:/comboboxtests/icons/movinghead.png&#39; }
            ListElement { theText: &#39;text2&#39;; theValue: &#39;value2&#39;; theIconUrl: &#39;qrc:/comboboxtests/icons/nebelmaschine.png&#39; }
            ListElement { theText: &#39;text3&#39;; theValue: &#39;value3&#39;; theIconUrl: &#39;qrc:/comboboxtests/icons/nebelmaschine.png&#39; }
            ListElement { theText: &#39;text4&#39;; theValue: &#39;value4&#39;; theIconUrl: &#39;qrc:/comboboxtests/icons/rgbstrahler.png&#39; }
            ListElement { theText: &#39;text5&#39;; theValue: &#39;value5&#39;; theIconUrl: &#39;qrc:/comboboxtests/icons/rgbstrahler.png&#39; }
        }
    }
    Label {
        text: qsTr(&#39;currentValue: &#39;) + listModelComboBox.currentValue
    }

    // IconComboBox shall support qml FolderListModels (to let the user select which icon to use)
    IconComboBox {
        Layout.preferredHeight: 64
        id: folderListModelComboBox
        textRole: &quot;fileBaseName&quot;
        valueRole: &quot;fileBaseName&quot;
        iconSourceRole: &quot;fileUrl&quot;
        model: FolderListModel {
            folder: &quot;qrc:/comboboxtests/icons/&quot;
            showDirs: false

            function getUrlForIcon(name) {
                let myFolder = folder;
                if (myFolder.length &lt; 1 || myFolder.charAt(myFolder.length - 1) !== &#39;/&#39;) {
                    myFolder = myFolder + &#39;/&#39;;
                }

                return myFolder + name + &quot;.png&quot;
            }
        }
    }
    Label {
        text: qsTr(&#39;currentValue: &#39;) + folderListModelComboBox.currentValue
    }

    // IconComboBox shall support C++ QAbstractListModels (access to our internal database)
    IconComboBox {
        Layout.preferredHeight: 64
        id: cppModelComboBox
        textRole: &#39;theText&#39;
        valueRole: &#39;theValue&#39;
        iconSourceRole: &#39;theIconUrl&#39;
        model: CppDefinedModel {

        }
    }
    Label {
        text: qsTr(&#39;currentValue: &#39;) + cppModelComboBox.currentValue
    }

    Item {
        Layout.fillHeight: true
    }
}

}


IcomComboBox.qml

import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Material
import Qt.labs.folderlistmodel 2.4
import comboboxtests 1.0

ComboBox {
id: comboBox

property string iconSourceRole

delegate: ItemDelegate {
    height: 64
    anchors.left: parent.left
    anchors.right: parent.right
    contentItem: IconChooserDelegateLayout {
        anchors.top: parent.top
        anchors.bottom: parent.bottom
        text: model[comboBox.textRole]
        iconSource: model[comboBox.iconSourceRole]
    }
}
contentItem: IconChooserDelegateLayout {
    text: comboBox.displayText
    isInsideMaterialComboBox: true
    iconSource: {

// console.log("QAbstractListModel", model instanceof QAbstractListModel);
// console.log("QAbstractItemModel", model instanceof QAbstractItemModel);
// console.log("FolderListModel", model instanceof FolderListModel);
// console.log("DeviceTypesModel", model instanceof CppDefinedModel);
// console.log("QtObject", model instanceof QtObject);

        if (comboBox.currentIndex &lt; 0)
            return &#39;&#39;;
        if (!comboBox.model)
            return &#39;&#39;;
        if (!comboBox.iconSourceRole)
            return &#39;&#39;;

        // FolderListModel has a different API
        if (model instanceof FolderListModel)
            return model.get(comboBox.currentIndex, iconSourceRole);
        // ListModel has another different API
        else if (&#39;get&#39; in model)
        {
            const data = model.get(comboBox.currentIndex);
            console.log(data);
            return data[iconSourceRole];
        }
        // and I dont know how to access C++ models from QML at all
        else if (&#39;roleNames&#39; in model || &#39;data&#39; in model)
        {
            if (!(&#39;roleNames&#39; in model &amp;&amp; &#39;data&#39; in model))
                throw &#39;roleNames or data not defined!&#39;;

            const roleNames = model.roleNames();
            console.log(&#39;roleNames&#39;, roleNames);

            const index = model.index(comboBox.currentIndex, 0);
            const data = model.data(index, 99);
            console.log(&#39;data&#39;, data);

            throw &#39;getting data from model using roleNames and data is not yet implemented.&#39;;
        }
        else
            throw &#39;unknown model type: &#39; + typeof model;
    }
}

}


cppdefinedmodel.h

#pragma once

#include <QAbstractListModel>
#include <qqml.h>

class CppDefinedModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT

enum {
    TextRole = Qt::UserRole,
    ValueRole,
    IconUrlRole
};

public:
using QAbstractListModel::QAbstractListModel;

int rowCount(const QModelIndex &amp;parent) const override
{
    return 6;
}
QVariant data(const QModelIndex &amp;index, int role) const override
{
    switch (role)
    {
    case TextRole:    return QString(&quot;name%0&quot;).arg(index.row());
    case ValueRole:   return QString(&quot;value%0&quot;).arg(index.row());
    case IconUrlRole: return QString(&quot;qrc:/comboboxtests/icons/%0.png&quot;)
                .arg(std::array&lt;const char *,3&gt;{{&quot;movinghead&quot;, &quot;nebelmaschine&quot;, &quot;rgbstrahler&quot;}}[index.row() / 2 % 3]);
    }
    return {};
}
QHash&lt;int, QByteArray&gt; roleNames() const override
{
    return {{TextRole, &quot;theText&quot;}, {ValueRole, &quot;theValue&quot;}, {IconUrlRole, &quot;theIconUrl&quot;}};
}

};


I think qml needs a unified interface to access the data models. Is the logic to handle all the different model types implemented in ListView and ComboBox&#39;s C++ implementation?
[I have commited this test project to GitHub][2]
[1]: https://i.stack.imgur.com/Lw7DO.png
[2]: https://github.com/0xFEEDC0DE64/comboboxtests
</details>
# 答案1
**得分**: 2
> 我认为qml需要一个统一的接口来访问数据模型。
它绝对需要 - 请参阅https://bugreports.qt.io/browse/QTBUG-111176,了解目前正在进行的工作。
> 用于处理不同模型类型的逻辑是否在ListView和ComboBox的C++实现中实现了?
如上面的链接所述,目前需要复杂的绑定来支持用户希望使用的各种模型类型:
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData
然而,在这种情况下,存在另一个问题,即您不在委托内。在这种情况下,没有方便的方式来访问模型中的数据:
https://bugreports.qt.io/browse/QTBUG-99115
在那之前,您可以通过比您当前的更简单的`iconSource`绑定来实现您想要的效果:
iconSource: comboBox.currentIndex === -1
? ""
: Array.isArray(comboBox.model)
? comboBox.model[comboBox.currentIndex][comboBox.iconSourceRole]
: (comboBox.model as ListModel)?.get(comboBox.currentIndex)[comboBox.iconSourceRole]
?? qrcPathOrUndefined((comboBox.model as FolderListModel)?.get(comboBox.currentIndex, "filePath"))
?? comboBox.model.data(comboBox.model.index(comboBox.currentIndex, 0), CppDefinedModel.IconUrlRole)
请注意以下几点:
- 我们使用[as-casts][1],[optional chaining][2]和[nullish coalescing][3]来使绑定更短。
- 我们定义了`qrcPathOrUndefined`函数,以允许使用nullish coalescing,还修复了FolderListModel给出的路径。我不确定它是否曾经被设计成与qrc路径一起使用,因为它应该返回一个以“qrc:”为前缀的路径以供QML使用,而不是它当前返回的面向C++的“:”。
- 这不适用于每种模型类型。具体来说,我不确定如何以通用方式使这适用于整数之类的模型。
- 它支持数组,但您的`delegate`实现需要修改以使用QTBUG-111176中提到的第一个绑定。
这还需要为您的模型的角色枚举命名,使其公开,并将其暴露给QML:
public:
enum Roles {
TextRole = Qt::UserRole,
ValueRole,
IconUrlRole
};
Q_ENUM(Roles);
为了确保ComboBox在启动时显示第一项,FolderListModel似乎也需要这个绑定:
currentIndex: model.status === FolderListModel.Ready ? 0 : -1
[1]: https://doc.qt.io/qt-6/qtqml-javascript-hostenvironment.html#type-annotations-and-assertions
[2]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
[3]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing
<details>
<summary>英文:</summary>
&gt; I think qml needs a unified interface to access the data models.
It absolutely does - see https://bugreports.qt.io/browse/QTBUG-111176 for work that is currently being done on this.
&gt; Is the logic to handle all the different model types implemented in ListView and ComboBox&#39;s C++ implementation?
As mentioned in the link above, a complex binding is currently required to support the various model types that users expect to be able to use:
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData
However, in this case there&#39;s the added problem that you&#39;re not inside a delegate. There&#39;s no convenient way of accessing data from the model in this situation:
https://bugreports.qt.io/browse/QTBUG-99115
Until then, you can achieve what you&#39;re after with a less complex `iconSource` binding than your current one:
iconSource: comboBox.currentIndex === -1
? &quot;&quot;
: Array.isArray(comboBox.model)
? comboBox.model[comboBox.currentIndex][comboBox.iconSourceRole]
: (comboBox.model as ListModel)?.get(comboBox.currentIndex)[comboBox.iconSourceRole]
?? qrcPathOrUndefined((comboBox.model as FolderListModel)?.get(comboBox.currentIndex, &quot;filePath&quot;))
?? comboBox.model.data(comboBox.model.index(comboBox.currentIndex, 0), CppDefinedModel.IconUrlRole)
function qrcPathOrUndefined(path) {
if (path === undefined)
return undefined
return path.startsWith(&quot;:/&quot;) ? &quot;qrc&quot; + path : undefined
}
A few things to note:
- We use [as-casts][1], [optional chaining][2], and [nullish coalescing][3] to make the binding shorter.
- We define the `qrcPathOrUndefined` function to allow the use of nullish coalescing and also to fix the path that FolderListModel gives us. I&#39;m not sure if it was ever designed to work with qrc paths, because it should return a path prefixed with &quot;qrc:&quot; for use with QML, rather than the C++-oriented &quot;:&quot; that it currently returns.
- This won&#39;t work with every model type. Specifically, I&#39;m not sure how you&#39;d make this work with models like integers in a generic way.
- It does support arrays, but your `delegate` implementation would need to be modified to use the first binding mentioned (the one from QTBUG-111176).
This also requires giving your model&#39;s role enum a name, making it public, and exposing it to QML:
public:
enum Roles {
TextRole = Qt::UserRole,
ValueRole,
IconUrlRole
};
Q_ENUM(Roles);
FolderListModel seems to also require this binding in ComboBox to ensure that the first item is displayed at startup:
currentIndex: model.status === FolderListModel.Ready ? 0 : -1
[1]: https://doc.qt.io/qt-6/qtqml-javascript-hostenvironment.html#type-annotations-and-assertions
[2]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
[3]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing
</details>
# 答案2
**得分**: 0
自从您已经在使用`ItemDelegate`,为什么不直接设置`icon.source`呢?
实际上,您可以使用您的建议来使其工作:`model[comboBox.iconSourceRole]`
此外,如果您的图像相对于qml源文件而言,您无需使用完全限定的`qrc:`引用图像。只需使用相对引用来指定图像,例如`"icons/rgbstrahler.png"`,而不是`"qrc:/comboboxtests/icons/rgbstrahler.png"`。
以下是仅包含`ComboBox`并填充了`icon.source`的演示代码:
```qml
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
ColumnLayout {
IconComboBox {
id: listModelComboBox
textRole: 'theText'
valueRole: 'theValue'
iconSourceRole: 'theIconUrl'
model: ListModel {
ListElement { theText: 'text0'; theValue: 'value0'; theIconUrl: 'icons/calc.svg' }
ListElement { theText: 'text1'; theValue: 'value1'; theIconUrl: 'icons/smile.svg' }
ListElement { theText: 'text2'; theValue: 'value2'; theIconUrl: 'icons/calc.svg' }
ListElement { theText: 'text3'; theValue: 'value3'; theIconUrl: 'icons/smile.svg' }
ListElement { theText: 'text4'; theValue: 'value4'; theIconUrl: 'icons/calc.svg' }
ListElement { theText: 'text5'; theValue: 'value5'; theIconUrl: 'icons/smile.svg' }
}
}
ItemDelegate {
text: qsTr("currentValue: %1").arg(listModelComboBox.currentValue)
}
ItemDelegate {
text: qsTr("currentText: %1").arg(listModelComboBox.currentText)
}
ItemDelegate {
text: qsTr("currentIconSource: %1").arg(listModelComboBox.currentIconSource)
icon.source: listModelComboBox.currentIconSource
}
}
}

您可以在线尝试!

英文:

Since you're already using ItemDelegate why don't you just set icon.source?

In fact, I can make it work using your suggestion: model[comboBox.iconSourceRole]

Also, if your images are located relative to the qml source, you do not need a fully qualified qrc: reference to your image. It's sufficient to use relative references for your images. e.g. &quot;icons/rgbstrahler.png&quot; instead of &quot;qrc:/comboboxtests/icons/rgbstrahler.png&quot;.

Here's a demonstration of just the ComboBox with the icon.source populated.

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
    ColumnLayout {
        IconComboBox {
            id: listModelComboBox
            textRole: &#39;theText&#39;
            valueRole: &#39;theValue&#39;
            iconSourceRole: &#39;theIconUrl&#39;
            model: ListModel {
                ListElement { theText: &#39;text0&#39;; theValue: &#39;value0&#39;; theIconUrl: &#39;icons/calc.svg&#39; }
                ListElement { theText: &#39;text1&#39;; theValue: &#39;value1&#39;; theIconUrl: &#39;icons/smile.svg&#39; }
                ListElement { theText: &#39;text2&#39;; theValue: &#39;value2&#39;; theIconUrl: &#39;icons/calc.svg&#39; }
                ListElement { theText: &#39;text3&#39;; theValue: &#39;value3&#39;; theIconUrl: &#39;icons/smile.svg&#39; }
                ListElement { theText: &#39;text4&#39;; theValue: &#39;value4&#39;; theIconUrl: &#39;icons/calc.svg&#39; }
                ListElement { theText: &#39;text5&#39;; theValue: &#39;value5&#39;; theIconUrl: &#39;icons/smile.svg&#39; }
            }
        }
        ItemDelegate {
            text: qsTr(&quot;currentValue: %1&quot;).arg(listModelComboBox.currentValue)
        }
        ItemDelegate {
            text: qsTr(&quot;currentText: %1&quot;).arg(listModelComboBox.currentText)
        }
        ItemDelegate {
            text: qsTr(&quot;currentIconSource: %1&quot;).arg(listModelComboBox.currentIconSource)
            icon.source: listModelComboBox.currentIconSource
        }
    }
}

// IconComboBox.qml
import QtQuick
import QtQuick.Controls
ComboBox {
    id: comboBox
    property string iconSourceRole
    property string currentIconSource: get(model, comboBox.currentIndex, comboBox.iconSourceRole)
    delegate: ItemDelegate {
        text: model[comboBox.textRole]
        icon.source: model[comboBox.iconSourceRole]
    }
    contentItem: ItemDelegate {
        text: currentText
        icon.source: currentIconSource
    }
    function get(obj, index, prop) {
        if (obj instanceof ListModel)
            return obj.get(index)[prop];
        if (obj instanceof FolderListModel)
            return obj.get(index, prop);
        return null;
    }
}

// icons/calc.svg
&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;32&quot; height=&quot;32&quot; viewBox=&quot;0 0 32 32&quot; class=&quot;svg-icon&quot;&gt;&lt;path d=&quot;M1 0v12h29.8V0H1zm27 9H4V3h24v6zM1 14v8h8v-8H1zm6 6H3v-4h4v4zm5-6v8h8v-8h-8zm6 6h-4v-4h4v4zm5-6v18h8V14h-8zm6 16h-4V16h4v14zM1 24v8h8v-8H1zm6 6H3v-4h4v4zm5-6v8h8v-8h-8zm6 6h-4v-4h4v4z&quot;/&gt;&lt;/svg&gt;

// icons/smile.svg

&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 32 32&quot;&gt;&lt;path d=&quot;M16 29.8A13.8 13.8 0 1 1 29.8 16 13.815 13.815 0 0 1 16 29.8zm0-26.6A12.8 12.8 0 1 0 28.8 16 12.815 12.815 0 0 0 16 3.2zm-4.5 10.6a1.2 1.2 0 0 0 .608-.168 1.52 1.52 0 0 0 .464-.43 1.927 1.927 0 0 0 .278-.572 2.234 2.234 0 0 0 0-1.26 1.927 1.927 0 0 0-.278-.571 1.52 1.52 0 0 0-.464-.431 1.185 1.185 0 0 0-1.216 0 1.52 1.52 0 0 0-.464.43 1.927 1.927 0 0 0-.277.572 2.234 2.234 0 0 0 0 1.26 1.927 1.927 0 0 0 .277.571 1.52 1.52 0 0 0 .464.431 1.2 1.2 0 0 0 .608.168zm9.608-.168a1.52 1.52 0 0 0 .464-.43 1.927 1.927 0 0 0 .278-.572 2.234 2.234 0 0 0 0-1.26 1.927 1.927 0 0 0-.278-.571 1.52 1.52 0 0 0-.464-.431 1.185 1.185 0 0 0-1.216 0 1.52 1.52 0 0 0-.464.43 1.927 1.927 0 0 0-.277.572 2.234 2.234 0 0 0 0 1.26 1.927 1.927 0 0 0 .277.571 1.52 1.52 0 0 0 .464.431 1.185 1.185 0 0 0 1.216 0zm3.223 5.743l-.926-.379a7.863 7.863 0 0 1-7.39 4.976.166.166 0 0 0-.032 0 7.863 7.863 0 0 1-7.388-4.976l-.926.379a8.846 8.846 0 0 0 8.313 5.597.21.21 0 0 0 .035 0 8.848 8.848 0 0 0 8.314-5.597z&quot;/&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h32v32H0z&quot;/&gt;&lt;/svg&gt;

You can Try it Online!

huangapple
  • 本文由 发表于 2023年2月27日 05:04:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/75575007.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定