You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Odoo 12表单中为单选按钮添加描述图标是否可行及实现方法

在Odoo 12中给单选按钮添加图标的实现方案

当然可以实现!在Odoo 12里,给单选按钮旁加图标、甚至多个带对应描述图标的单选框都完全没问题,我来给你一步步拆解具体操作:

一、核心思路

Odoo表单默认的单选按钮(也就是selection字段)没有直接内置图标支持,但咱们可以通过自定义QWeb模板或者扩展原生radio widget的方式来搞定——本质就是在渲染每个单选选项的时候,把图标元素插进去就行。

二、具体操作步骤

1. 先定义带图标标识的选择字段

首先在你的模型里定义一个selection字段,咱们可以把图标类名(比如Font Awesome的类)和选项文本放在一起,用分隔符分开,方便后续渲染。举个例子,做一个用户显示偏好的单选选项:

from odoo import models, fields

class ResUsers(models.Model):
    _inherit = 'res.users'

    # 用|分隔选项文本和图标类
    preference = fields.Selection([
        ('light', '浅色模式|fa-sun-o'),
        ('dark', '深色模式|fa-moon-o'),
        ('system', '跟随系统|fa-desktop'),
    ], string='显示偏好', default='light')

2. 自定义QWeb模板渲染带图标的单选按钮

Odoo默认的radio按钮有对应的QWeb模板,咱们可以继承它并修改,在每个选项后面加上图标。在模块的views目录下创建一个XML文件(比如radio_icon_templates.xml):

<odoo>
    <!-- 继承原生radio模板,添加图标 -->
    <template id="radio_with_icon_template" inherit_id="web.radio" name="Radio Button with Icon">
        <xpath expr="//td[hasclass('o_radio_item')]" position="inside">
            <t t-set="label_parts" t-value="widget.field.selection_options[option_value][1].split('|')"/>
            <!-- 只有当存在图标类时才渲染 -->
            <t t-if="label_parts.length == 2">
                <span t-attf-class="fa {{ label_parts[1] }} ml-2"/>
                <!-- 把选项文本单独显示,去掉图标类部分 -->
                <t t-set="widget.field.selection_options[option_value][1]" t-value="label_parts[0]"/>
            </t>
        </xpath>
    </template>
</odoo>

这里用了Odoo默认集成的Font Awesome 4.x图标,所以直接用对应的类名就行,不用额外引入资源。

3. 在表单视图中应用自定义模板

接下来在你的表单视图里,给这个字段指定使用咱们的自定义模板。比如继承用户表单视图,添加这个字段:

<odoo>
    <record id="res_users_form_inherit" model="ir.ui.view">
        <field name="name">res.users.form.inherit.icon.radio</field>
        <field name="model">res.users</field>
        <field name="inherit_id" ref="base.view_users_form"/>
        <field name="arch" type="xml">
            <!-- 把字段加在邮箱字段后面 -->
            <xpath expr="//field[@name='email']" position="after">
                <field name="preference" widget="radio" options="{'template': 'your_module_name.radio_with_icon_template'}"/>
            </xpath>
        </field>
    </record>
</odoo>

记得把your_module_name换成你自己的模块名称哦。

4. 更灵活的方式:自定义Widget

如果你需要更复杂的逻辑(比如动态切换图标、自定义样式),可以写一个自定义的radio widget。在模块的static/src/js目录下创建radio_with_icon.js:

odoo.define('your_module_name.radio_with_icon_widget', function(require) {
    "use strict";

    var core = require('web.core');
    var Radio = require('web.Radio');

    // 继承原生Radio widget,重写渲染选项的方法
    var RadioWithIcon = Radio.extend({
        _renderItem: function(id, label, value) {
            // 先调用原生方法渲染基础的单选按钮
            var $item = this._super(id, label, value);
            // 拆分选项文本和图标类
            var labelParts = label.split('|');
            if (labelParts.length === 2) {
                // 在标签后面添加图标
                $item.find('.o_radio_label').after('<span class="fa ' + labelParts[1] + ' ml-2"></span>');
                // 更新标签文本,只显示选项名称
                $item.find('.o_radio_label').text(labelParts[0]);
            }
            return $item;
        },
    });

    // 把自定义widget注册到表单组件里
    core.form_widget_registry.add('radio_with_icon', RadioWithIcon);
    return RadioWithIcon;
});

然后在XML里加载这个JS文件,让Odoo能识别它:

<odoo>
    <template id="assets_backend_radio_icon" inherit_id="web.assets_backend">
        <xpath expr="." position="inside">
            <script type="text/javascript" src="/your_module_name/static/src/js/radio_with_icon.js"/>
        </xpath>
    </template>
</odoo>

之后在表单视图里直接用这个自定义widget就行:

<field name="preference" widget="radio_with_icon"/>

三、几个注意点

  • 记得在模块的__manifest__.py里添加'depends': ['web'],确保依赖web模块
  • Odoo 12用的是Font Awesome 4.x,所以图标类要对应这个版本(比如fa-sun-o,不是新版的fa-sun)
  • 如果要用自己的自定义图标,把图标路径存在selection里,然后把模板里的<span>换成<img>标签就行

这样就能实现每个单选按钮旁都带对应描述图标的需求啦!

内容的提问来源于stack exchange,提问作者Adham Baquroun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:49:33