I am just downloaded gtk3+, and I'm working through some sample code from:
https://python-gtk-3-tutorial.readthedocs.io/en/latest/layout.html#listbox
Here is the sample code:
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class ListBoxRowWithData(Gtk.ListBoxRow):
def __init__(self, data):
super(Gtk.ListBoxRow, self).__init__()
self.data = data
self.add(Gtk.Label(data))
class ListBoxWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="ListBox Demo")
self.set_border_width(10)
box_outer = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
self.add(box_outer)
listbox = Gtk.ListBox()
listbox.set_selection_mode(Gtk.SelectionMode.NONE)
box_outer.pack_start(listbox, True, True, 0)
row = Gtk.ListBoxRow()
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=50)
row.add(hbox)
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
hbox.pack_start(vbox, True, True, 0)
label1 = Gtk.Label("Automatic Date & Time", xalign=0)
label2 = Gtk.Label("Requires internet access", xalign=0)
vbox.pack_start(label1, True, True, 0)
vbox.pack_start(label2, True, True, 0)
switch = Gtk.Switch()
switch.props.valign = Gtk.Align.CENTER
hbox.pack_start(switch, False, True, 0)
listbox.add(row)
row = Gtk.ListBoxRow()
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=50)
row.add(hbox)
label = Gtk.Label("Enable Automatic Update", xalign=0)
check = Gtk.CheckButton()
hbox.pack_start(label, True, True, 0)
hbox.pack_start(check, False, True, 0)
listbox.add(row)
row = Gtk.ListBoxRow()
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=50)
row.add(hbox)
label = Gtk.Label("Date Format", xalign=0)
combo = Gtk.ComboBoxText()
combo.insert(0, "0", "24-hour")
combo.insert(1, "1", "AM/PM")
hbox.pack_start(label, True, True, 0)
hbox.pack_start(combo, False, True, 0)
listbox.add(row)
listbox_2 = Gtk.ListBox()
items = 'This is a sorted ListBox Fail'.split()
for item in items:
listbox_2.add(ListBoxRowWithData(item))
def sort_func(row_1, row_2, data, notify_destroy):
return row_1.data.lower() > row_2.data.lower()
def filter_func(row, data, notify_destroy):
return False if row.data == 'Fail' else True
listbox_2.set_sort_func(sort_func, None, False)
listbox_2.set_filter_func(filter_func, None, False)
listbox_2.connect('row-activated', lambda widget, row: print(row.data))
box_outer.pack_start(listbox_2, True, True, 0)
listbox_2.show_all()
win = ListBoxWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
I get an error of "incorrect syntax" in
listbox_2.connect('row-activated', lambda widget, row: print(row.data))
This is straight from the sample code, and I'm completely at a loss here. Please help.
Other way for your problem instead of import print function is use repr()
listbox_2.connect('row-activated', lambda widget, row: repr(row.data))
You can use this way too:
def on_row_activated(listbox, row):
print(row.data)
listbox_2.connect('row-activated', on_row_activated)
References: https://github.com/ailtonbsj/course-python-gtk3/blob/master/listBoxLayout.py
https://lazka.github.io/pgi-docs/Gtk-3.0/classes/ListBox.html#Gtk.ListBox.signals.row_activated
Related
When i call the below function through API;
In both try and except conditions I have to keep log in separate table named api.log.
While the function enters in except condition, error occurs on creating record on api.log table
Here is the code:
#http.route('/tax_master',type="json",methodn ['POST'],auth="public",csrf=Falenter code herese)
def create_tax_master(self,**kw):
kw = http.request.params
obj_tax_master = request.env['tax.master']
obj_account_tax = request.env['account.tax']
flag = kw.get('flag')
vals = {}
result = False
if kw.get('name'):
vals['name'] = kw.get('name')
if kw.get('value'):
vals['value'] = kw.get('value')
if kw.get('scope'):
vals['scope'] = kw.get('scope')
if kw.get('is_excise'):
vals['is_excise'] = kw.get('is_excise')
if kw.get('description'):
vals['description'] = kw.get('description')
if kw.get('amount_type'):
vals['amount_type']= kw.get('amount_type')
if 'is_excise' in kw and kw.get('is_excise') not in [1,0]:
result = json.dumps({
"statusCode":02,
"statusDesc":"The value for the field is_excise should be 0 or 1"})
try:
if flag == 'create':
tax_id = obj_tax_master.sudo().create(vals).id
result = json.dumps({"id":tax_id,
"statusCode":01,
"statusDesc":"Successfully Created"
})
elif flag == 'write':
if kw.get('id'):
tax_id_rec = obj_tax_master.sudo().browse([int(kw.get('id'))])
if tax_id_rec.active == False:
result = json.dumps({
'statusCode': 02,
'statusDesc': 'The Tax is Archived.Updation is not possible now',
})
else:
tax_id_rec.sudo().write(vals)
tax_id = kw.get('id')
result = json.dumps({"id":tax_id,
"statusCode":01,
"statusDesc":"Successfully Updated"
})
else:
result = json.dumps({
'statusCode' : 02,
'statusDesc' : 'Please provide valid id to update the record',
})
elif flag == 'delete':
tax_id = obj_tax_master.sudo().browse(int(kw.get('id')))
if tax_id.active == False:
result = json.dumps({
'statusCode': 02,
'statusDesc': 'The record is already archived!!!',
})
else:
tax_id.write({'active':False})
taxes = obj_account_tax.sudo().search([('tax_master_id','=',kw.get('id'))])
for tax in taxes:
tax.write({'active':False})
result = json.dumps({
'statusCode' : 01,
'statusDesc' : 'The record is archived successfully!!!',
})
data = json.loads(result)
self.create_api_log('tax_master', flag, kw, data)
return data
except Exception,e:
result = json.dumps({'statusCode' : 02,'statusDesc' : str(e),})
data = json.loads(result)
self.create_api_log('tax_master', flag, kw, data)
return data
It is solved by using commit function.
I am trying to set a different color on every second row in XLSX file. From the documentation I see that I can pass some conditions using body property or get_body() method, but this only allows me to set somewhat "static" conditions. Here is the ViewSet config responsible for rendering the XLSX file:
class MyViewSet(XLSXFileMixin, ModelViewSet):
def get_renderers(self) -> List[BaseRenderer]:
if self.action == "export":
return [XLSXRenderer()]
else:
return super().get_renderers()
#action(methods=["GET"], detail=False)
def export(self, request: Request) -> Response:
serializer = self.get_serializer(self.get_queryset(), many=True)
return Response(serializer.data)
# Properties for XLSX
column_header = {
"titles": [
"Hostname", "Operating System", "OS name", "OS family", "OS version", "Domain", "Serial number",
"Available patches",
],
"tab_title": "Endpoints",
"style": {
"font": {
"size": 14,
"color": "FFFFFF",
},
"fill": {
"start_color": "3F803F",
"fill_type": "solid",
}
}
}
body = {
"style": {
"font": {
"size": 12,
"color": "FFFFFF"
},
"fill": {
"fill_type": "solid",
"start_color": "2B2B2B"
},
}
}
OK. I got the answer after some digging through the source code. The render method of XLSXRenderer has this piece of code:
for row in results:
column_count = 0
row_count += 1
flatten_row = self._flatten(row)
for column_name, value in flatten_row.items():
if column_name == "row_color":
continue
column_count += 1
cell = ws.cell(
row=row_count, column=column_count, value=value,
)
cell.style = body_style
ws.row_dimensions[row_count].height = body.get("height", 40)
if "row_color" in row:
last_letter = get_column_letter(column_count)
cell_range = ws[
"A{}".format(row_count): "{}{}".format(last_letter, row_count)
]
fill = PatternFill(fill_type="solid", start_color=row["row_color"])
for r in cell_range:
for c in r:
c.fill = fill
So when I added a field row_color in my serializer as SerializerMethodField I was able to define a function that colors rows:
def get_row_color(self, obj: Endpoint) -> str:
"""
This method returns color value for row in XLSX sheet.
(*self.instance,) extends queryset to a list (it must be a queryset, not a single Endpoint).
.index(obj) gets index of currently serialized object in that list.
As the last step one out of two values from the list is chosen using modulo 2 operation on the index.
"""
return ["353535", "2B2B2B"][(*self.instance,).index(obj) % 2]
In Odoo v10 this on_change method worked pretty well:
#api.onchange("partner_id")
def onchange_partner_id(self):
self.zapocet_line_pohledavky = False
self.zapocet_line_zavazky = False
account_move_line_obj = self.env['account.move.line']
val = {'value': {'zapocet_line_pohledavky': [], 'zapocet_line_zavazky': []}}
for statement in self:
if statement.partner_id:
domain = [('account_id.user_type_id.type', 'in', ('payable', 'receivable')), ('move_id.state', '=', 'posted'),
('partner_id.id', '=', statement.partner_id.id),]
line_ids = account_move_line_obj.search(domain, order="date asc")
for line in line_ids:
if line.amount_residual != 0 and line.credit > 0:
res = {
"move_line_id": line.id,
}
val['value']['zapocet_line_zavazky'].append(res)
if line.amount_residual != 0 and line.debit > 0:
qes = {
"move_line_id": line.id,
}
val['value']['zapocet_line_pohledavky'].append(qes)
self.zapocet_line_pohledavky = val['value']['zapocet_line_pohledavky']
return val
Does anybody have a clue why in v11 it loads the lines well, but they disappear on saving?
I'm using Glade 3.20 but i don't known how to make a toggle column editable. I do not see any options.
screenshots
Please help me!
Look at this CellRendererToggle usage example (in python).
The source (in case the link breaks someday):
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class CellRendererToggleWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="CellRendererToggle Example")
self.set_default_size(200, 200)
self.liststore = Gtk.ListStore(str, bool, bool)
self.liststore.append(["Debian", False, True])
self.liststore.append(["OpenSuse", True, False])
self.liststore.append(["Fedora", False, False])
treeview = Gtk.TreeView(model=self.liststore)
renderer_text = Gtk.CellRendererText()
column_text = Gtk.TreeViewColumn("Text", renderer_text, text=0)
treeview.append_column(column_text)
renderer_toggle = Gtk.CellRendererToggle()
renderer_toggle.connect("toggled", self.on_cell_toggled)
column_toggle = Gtk.TreeViewColumn("Toggle", renderer_toggle, active=1)
treeview.append_column(column_toggle)
renderer_radio = Gtk.CellRendererToggle()
renderer_radio.set_radio(True)
renderer_radio.connect("toggled", self.on_cell_radio_toggled)
column_radio = Gtk.TreeViewColumn("Radio", renderer_radio, active=2)
treeview.append_column(column_radio)
self.add(treeview)
def on_cell_toggled(self, widget, path):
self.liststore[path][1] = not self.liststore[path][1]
def on_cell_radio_toggled(self, widget, path):
selected_path = Gtk.TreePath(path)
for row in self.liststore:
row[2] = (row.path == selected_path)
win = CellRendererToggleWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
I am writing a script which has an UI in Maya. I have a text box that is supposed to constantly update based on the last item in the users selection list. How would I go about something that constantly keeps checken whithout having the user to push a button or something manually to call a function.
Thx
Edit: Cool that is what I was looking for. Thx. Your script works just fine. I tried implementing that into my big script which resulted in that every button in the UI had to be pushed twice in order to take effect. But I will deal with that later. However testing my own version in a seperate script as follows sometimes produces the following error: 'sl' must be passed a boolean argument
#________________________________________________________________________________________________________________________________________________
import maya.cmds as cmds
idManagerUI = cmds.window(title='Vray ID Manager', s = False, wh = (305,500))
cmds.columnLayout(adj = True)
cmds.text (l = '__________________________________________ \n your current selection has this ID: \n')
curSelTxt = cmds.text (l = '', backgroundColor = [0.2, 0.2, 0.2])
def update_label(*_):
upCurrentObjectSel = cmds.ls(sl=True)
upCurrentObjectSelShapes = cmds.listRelatives(upCurrentObjectSel)
upLastobj = upCurrentObjectSelShapes[-1]
print upLastobj
cmds.text(curSelTxt, e=True, label = upLastobj)
cmds.scriptJob(event=("SelectionChanged", update_label), p= curSelTxt)
cmds.showWindow(idManagerUI)
Also, making two of these ScriptJobs makes the script stop working properly entirely.
#________________________________________________________________________________________________________________________________________________
import maya.cmds as cmds
idManagerUI = cmds.window(title='Vray ID Manager', s = False, wh = (305,500))
cmds.columnLayout(adj = True)
cmds.text (l = '__________________________________________ \n your current selection has this ID: \n')
curSelObjTxt = cmds.text (l = '', backgroundColor = [0.2, 0.2, 0.2])
curSelShadTxt = cmds.text (l = '', backgroundColor = [0.2, 0.2, 0.2])
def update_obj_label(*_):
upCurrentObjectSel = cmds.ls(sl=True)
upCurrentObjectSelShapes = cmds.listRelatives(upCurrentObjectSel)
upLastobj = upCurrentObjectSelShapes[-1]
objID = cmds.getAttr(upLastobj + '.vrayObjectID')
print objID
cmds.text(curSelObjTxt, e=True, label = objID)
def update_shader_label(*_):
upCurrentShaderSel = cmds.ls(sl=True, type= shaderTypes)
upCurrentShaderSelLast = upCurrentShaderSel[-1]
shadID = cmds.getAttr(upCurrentShaderSelLast + '.vrayMaterialId')
cmds.text(curSelShadTxt, e=True, label = shadID)
print shadID
cmds.scriptJob(event=("SelectionChanged", update_obj_label), p= curSelObjTxt)
cmds.scriptJob(event=("SelectionChanged", update_shader_label), p= curSelShadTxt)
cmds.showWindow(idManagerUI)
Edit:
still your latest version of the script produces the error from time to time.
Also, I noticed in my own version of it, that it sometimes works lovely, then not at all, once I e.g. switched my active window to Firefox or so and then get back to Maya, and sometimes it does not work at all. That is with just one of the functions in my script. With both of them (s.below) it is totally unusable. Very unstable results.
import maya.cmds as cmds
def curSelTxtShower():
idManagerUI = cmds.window(title='Vray ID Manager', s = False, wh = (305,500))
cmds.columnLayout(adj = True)
cmds.text (l = '__________________________________________ \n your current selection has this ID: \n')
curSelObjTxt = cmds.text (l = '', backgroundColor = [0.2, 0.2, 0.2])
curSelShadTxt = cmds.text (l = '', backgroundColor = [0.2, 0.2, 0.2])
def update_obj_label(*_):
upCurrentObjectSelShapes = cmds.listRelatives(s=True) or ["nothing selected"]
upLastobj = upCurrentObjectSelShapes[-1]
if upLastobj is not "nothing selected":
if cmds.attributeQuery('vrayObjectID', node = upLastobj, ex = True) is True:
objID = cmds.getAttr(upLastobj + '.vrayObjectID')
cmds.text(curSelObjTxt, e=True, label = objID)
else:
cmds.text(curSelObjTxt, e=True, label = 'curSel has no ObjID assigned')
def update_shader_label(*_):
upCurrentShaderSel = cmds.ls(sl=True, type= shaderTypes)
upCurrentShaderSelLast = upCurrentShaderSel[-1]
if cmds.attributeQuery('vrayMaterialId', node = upCurrentShaderSelLast, ex = True) is True:
shadID = cmds.getAttr(upCurrentShaderSelLast + '.vrayMaterialId')
cmds.text(curSelShadTxt, e=True, label = shadID)
print shadID
else:
cmds.text(curSelShadTxt, e=True, label = 'curSel has no MatID assigned')
cmds.scriptJob(event=("SelectionChanged", lambda *x: update_obj_label()), p= curSelObjTxt)
cmds.scriptJob(event=("SelectionChanged", lambda *x: update_shader_label()), p= curSelShadTxt)
cmds.showWindow(idManagerUI)
curSelTxtShower()
You need to use a scriptJob to watch for selection change events and respond. You'll want to parent the scriptJob to a particular piece of UI so it deletes itself when the UI object goes away.
An absolutely minimal example looks like this:
import maya.cmds as cmds
wind = cmds.window()
col = cmds.columnLayout()
txt = cmds.text(label="", width = 240)
def update_label(*_):
cmds.text(txt, e=True, label = str(cmds.ls(sl=True)))
cmds.scriptJob(event=("SelectionChanged", update_label), p= txt)
cmds.showWindow(wind)
Edit
This version of OP's code helps avoid the false error message. the actual error was happening when due to an empty selection - but the scriptJob falsely reports it in the previous line:
def scoped():
idManagerUI = cmds.window(title='Vray ID Manager', s = False, wh = (305,500))
cmds.columnLayout(adj = True)
cmds.text (l = '__________________________________________ \n your current selection has this ID: \n')
curSelTxt = cmds.text (l = '', backgroundColor = [0.2, 0.2, 0.2])
def update_label(*_):
# listRelatives works off the current selection already
upCurrentObjectSelShapes = cmds.listRelatives(s=True) or ["nothing selected"]
upLastobj = upCurrentObjectSelShapes[-1]
cmds.text(curSelTxt, e=True, label = upLastobj)
cmds.showWindow(idManagerUI)
cmds.scriptJob(event=("SelectionChanged", update_label), p= idManagerUI)
scoped()