OpenERP 7:如何制作一个按钮,在剪贴板中插入预定义的文本?

OpenERP 7 : How can I make a button inserting a predefined text in the Clipboard?

我是 OpenERP 的新手 Python 这是我的问题 :

在表单视图中,用户可以看到他的一位客户的地址,我的任务是添加一个按钮,当用户单击该按钮时,该按钮会将地址保存在剪贴板中,因此用户只需粘贴在他想要的地方,而不是选择文本并制作快捷键来复制它。

这是我尝试过的最后一件事,人们在 Internet 上给出的许多不同答案让我有点迷茫,而且我对功能还不是很满意:

from openerp.osv import fields, orm
import sys
import gtk
import pygtk
pygtk.require('2.0')


class address_copy(orm.Model):

    _inherit = "res.partner"

    def address_copy(self, cr, uid, ids, context=None):
        if context is None:
            context = {}
        address = partner.street + '\n' + partner.zip + ' ' + partner.city + '\n' + partner.country_id + ', ' + partner.state_id
        self.clipboard_clear()
        self.clipboard_append(address)

当我用这个模块更新我的数据库时没有任何问题,但是当我点击我创建的按钮时,我有这个错误:

2015-05-01 15:45:12,305 20229 ERROR Armand openerp.osv.osv: Uncaught exception
Traceback (most recent call last):
 File "/home/odoo/server/7.0/openerp/osv/osv.py", line 132, in wrapper
  return f(self, dbname, *args, **kwargs)
 File "/home/odoo/server/7.0/openerp/osv/osv.py", line 199, in execute
  res = self.execute_cr(cr, uid, obj, method, *args, **kw)
 File "/home/odoo/server/7.0/openerp/osv/osv.py", line 187, in execute_cr
  return getattr(object, method)(cr, uid, *args, **kw)
 File "/home/odoo/addons/7.0/purchase/partner.py", line 44, in copy
  return super(res_partner, self).copy(cr, uid, id, default=default, context=context)
TypeError: copy() got an unexpected keyword argument 'default'
2015-05-01 15:45:12,305 20229 ERROR Armand openerp.netsvc: copy() got an unexpected keyword argument 'default'
Traceback (most recent call last):
 File "/home/odoo/server/7.0/openerp/netsvc.py", line 296, in dispatch_rpc
  result = ExportService.getService(service_name).dispatch(method, params)
 File "/home/odoo/server/7.0/openerp/service/web_services.py", line 626, in dispatch
  res = fn(db, uid, *params)
 File "/home/odoo/server/7.0/openerp/osv/osv.py", line 190, in execute_kw
  return self.execute(db, uid, obj, method, *args, **kw or {})
 File "/home/odoo/server/7.0/openerp/osv/osv.py", line 132, in wrapper
  return f(self, dbname, *args, **kwargs)
 File "/home/odoo/server/7.0/openerp/osv/osv.py", line 199, in execute
  res = self.execute_cr(cr, uid, obj, method, *args, **kw)
 File "/home/odoo/server/7.0/openerp/osv/osv.py", line 187, in execute_cr
  return getattr(object, method)(cr, uid, *args, **kw)
 File "/home/odoo/addons/7.0/purchase/partner.py", line 44, in copy
  return super(res_partner, self).copy(cr, uid, id, default=default, context=context)
TypeError: copy() got an unexpected keyword argument 'default'

所以看起来问题出在partner.py中的这个复制函数,虽然我的class继承了这个模块,但我没有改变它的任何东西,我真的不知道如何有用。 这是 partner.py 中的复制函数:

from openerp.osv import fields, osv

class res_partner(osv.osv):
    _name = 'res.partner'
    _inherit = 'res.partner'

    def copy(self, cr, uid, id, default=None, context=None):
        if default is None:
            default = {}

        default.update({'purchase_order_ids': []})

    return super(res_partner, self).copy(cr, uid, id, default=default, context=context)

    _columns = {
        'property_product_pricelist_purchase': fields.property('product.pricelist', type='many2one', relation='product.pricelist', domain=[('type','=','purchase')], string="Purchase Pricelist", view_load=True, help="This pricelist will be used, instead of the default one, for purchases from the current partner"),
        'purchase_order_count': fields.function(_purchase_order_count, string='# of Purchase Order', type='integer'),
        'purchase_order_ids': fields.one2many('purchase.order','partner_id','Purchase Order')
    }
res_partner()

你知道我怎样才能让它发挥作用吗?我的功能也可能是错误的。在此先感谢所有愿意帮助我的人!如果太复杂,也许一个只选择文本的按钮,用户可以直接复制它。

编辑:如果我尝试从 OpenERP 的销售模块启动它,使用一个简单的按钮和一个函数 "pyperclip.copy("string"),我得到这个错误:

OpenERP Server Error

Client Traceback (most recent call last):
 File "/home/odoo/web/7.0/addons/web/http.py", line 204, in dispatch response["result"] = method(self, **self.params)
 File "/home/odoo/web/7.0/addons/web/controllers/main.py", line 1132, in call_button
  action = self._call_kw(req, model, method, args, {})
 File "/home/odoo/web/7.0/addons/web/controllers/main.py", line 1120, in _call_kw
  return getattr(req.session.model(model), method)(*args, **kwargs)
 File "/home/odoo/web/7.0/addons/web/session.py", line 42, in proxy
  result = self.proxy.execute_kw(self.session._db, self.session._uid, self.session._password, self.model, method, args, kw)
 File "/home/odoo/web/7.0/addons/web/session.py", line 30, in proxy_method
  result = self.session.send(self.service_name, method, *args)
 File "/home/odoo/web/7.0/addons/web/session.py", line 103, in send
  raise xmlrpclib.Fault(openerp.tools.ustr(e), formatted_info)


Server Traceback (most recent call last):
 File "/home/odoo/web/7.0/addons/web/session.py", line 89, in send
  return openerp.netsvc.dispatch_rpc(service_name, method, args)
 File "/home/odoo/server/7.0/openerp/netsvc.py", line 296, in dispatch_rpc
  result = ExportService.getService(service_name).dispatch(method, params)
 File "/home/odoo/server/7.0/openerp/service/web_services.py", line 626, in dispatch
  res = fn(db, uid, *params)
 File "/home/odoo/server/7.0/openerp/osv/osv.py", line 190, in execute_kw
  return self.execute(db, uid, obj, method, *args, **kw or {})
 File "/home/odoo/server/7.0/openerp/osv/osv.py", line 132, in wrapper
  return f(self, dbname, *args, **kwargs)
 File "/home/odoo/server/7.0/openerp/osv/osv.py", line 199, in execute
  res = self.execute_cr(cr, uid, obj, method, *args, **kw)
 File "/home/odoo/server/7.0/openerp/osv/osv.py", line 187, in execute_cr
  return getattr(object, method)(cr, uid, *args, **kw)
 File "/home/odoo/personnal_addons/sale_option/sale_option.py", line 664, in copy
  return super(sale_order, self).copy(cr, uid, id, default, context=context)
 File "/home/odoo/addons/7.0/sale_stock/sale_stock.py", line 49, in copy
  return super(sale_order, self).copy(cr, uid, id, default, context=context)
 File "/home/odoo/addons/7.0/sale/sale.py", line 87, in copy
  return super(sale_order, self).copy(cr, uid, id, default, context=context)
 File "/home/odoo/server/7.0/openerp/osv/orm.py", line 5126, in copy
  data = self.copy_data(cr, uid, id, default, context)
 File "/home/odoo/addons/7.0/mail/mail_thread.py", line 326, in copy_data
  return super(mail_thread, self).copy_data(cr, uid, id, default=default, context=context)
 File "/home/odoo/server/7.0/openerp/osv/orm.py", line 5023, in copy_data
  data = self.read(cr, uid, [id], fields_to_copy.keys(), context=context)
 File "/home/odoo/server/7.0/openerp/osv/orm.py", line 3679, in read
  result = self._read_flat(cr, user, select, fields, context, load)
 File "/home/odoo/server/7.0/openerp/osv/orm.py", line 3730, in _read_flat for sub_ids in cr.split_for_in_conditions(ids):
 File "/home/odoo/server/7.0/openerp/sql_db.py", line 258, in split_for_in_conditions
  return tools.misc.split_every(self.IN_MAX, set(ids))
TypeError: unhashable type: 'list'

你的代码有很多问题。因此,在您清除最多之前,很难找到问题。

在此代码中,

address = partner.street + '\n' + partner.zip + ' ' + partner.city + '\n' + partner.country_id + ', ' + partner.state_id

您没有 partner 对象来获取地址详细信息。

然后在这段代码中,

partner.country_idpartner.state_id 你会得到一个对象。所以你需要使用 partner.country_id.name 或你需要的任何字段。

然后在这段代码中,我希望您尝试使用 tkinter 模块来执行剪贴板操作。

self.clipboard_clear()
self.clipboard_append(address)

为此,您需要 tkinter class 中的对象。它是一个跨平台的 GUI 库。试试这个

from openerp.osv import fields, orm
from Tkinter import Tk

class address_copy(orm.Model):

    _inherit = "res.partner"

    def address_copy(self, cr, uid, ids, context=None):
        if context is None:
            context = {}
        for partner in self.browse(cr, uid, ids, context=context):
            r = Tk()
            address = str(partner.street) + '\n' + str(partner.zip) + ' ' + str(partner.city) + '\n' + str(partner.country_id.name) + ', ' + str(partner.state_id.name)
            r.withdraw()
            r.clipboard_clear()
            r.clipboard_append(address)
            r.destroy()

在python3中,from Tkinter import Tk应该是from tkinter import Tk。由于 Odoo 使用上面的 python2.x 不会有问题。

或者您可以使用 pyperclip 模块。使用最少的代码即可正常工作。

简单示例:

import pyperclip
pyperclip.copy('The text to be copied to the clipboard.')
spam = pyperclip.paste()
print spam

对于你的情况:

from openerp.osv import fields, orm
import pyperclip

class address_copy(orm.Model):

    _inherit = "res.partner"

    def address_copy(self, cr, uid, ids, context=None):
        if context is None:
            context = {}
        for partner in self.browse(cr, uid, ids, context=context):
            address = str(partner.street) + '\n' + str(partner.zip) + ' ' + str(partner.city) + '\n' + str(partner.country_id.name) + ', ' + str(partner.state_id.name)
            pyperclip.copy(address)

我个人比较喜欢最后一种方法