I'm doing a form that contains a QListView. It's populated from database with this code:
model = QStandardItemModel(self.listUser)
for row in self.SELECT_USERS_ACCOUNTS():
item = QStandardItem(str(row[1]))
model.appendRow(item)
self.listUser.setModel(model)
My QListView is named listUser and SELECT_USERS_ACCOUNTS() function returns data created by select id,name from table_user, I need to store row[0] (id column in the table_user) too because when the user will click an item into the QListView. I want to capture this Id. Thanks in advance.
In QStandardItem data for different roles can be stored by setData(data, role).
Stored data are returned by data(role).
Roles >= 256 (0x100) are UserRoles, see documentation
so you can store the id by
item.setData(row[0],256)
and ask it by
item.data(256)
edit 31.03.2015:
for row in self.SELECT_USERS_ACCOUNTS():
item = QStandardItem(str(row[1]))
# add userData to item
item.setData(row[0],256)
# item.setData(row[2], 257) and so on if there are further columns in row
model.appendRow(item)
self.listUser.setModel(model)
self.listUser.clicked.connect(self.getUserData)
def getUserData(self,index):
item = self.model().item(index.row(),index.column())
iId = item.data(256)
# xyz = item.data(257) for further columns
print(iId) # or do anything else
Related
i want to add this returned list from get_famille_list function to selection field in odoo-15
get_famille_list function :
def get_famille_list(self):
all_fam = []
query = """ SELECT x FROM product_template WHERE x !='' """
self.env.cr.execute(query)
data = self.env.cr.fetchall()
for fam in data:
all_fam.append(fam[0])
return all_fam
And this is how i link the selection with the returned list from get_famille_list function
famille = fields.Selection(selection='get_famille_list')
expected data (selection= x1,x2,x3)
insteed of showing the correct data in the selection field it shows something weird, see the image
i can't figure out why it shows this.
any help will be appreciated, Thanks
You need to return a list of pairs (value, label).
You just need to append a tuple to the all_fam list
Example:
def get_famille_list(self):
all_fam = []
query = """ SELECT x FROM product_template WHERE x !='' """
self.env.cr.execute(query)
data = self.env.cr.fetchall()
for fam in data:
all_fam.append((fam[0], fam[0].capitalize()))
return all_fam
Hay I am new to Odoo Customizing and Python and wanted to know how I can iterate through a field and take the values out of the field and put them in a new one.
The field I want to iterate through contains multiple email adresses. I want to iterate through these email adress fields, collect the email adresses and store them together in a new field.
For that I need a function.
The field I want to iterate through:
My One2many field contains multiple mail adresses which I want to iterate through and collect.
field_contacts_customer_info = fields.One2many(
'contacts.customer.information', 'another_id', string='Contacts for customer information')
The field I want to store the collected email adresses in:
selected_email = fields.Char(compute='compute_email')
This is my class:
I want to collect all the email adresses from the mail_contacts field.
_name = 'contacts.customer.information'
_rec_name = 'name_contacts'
name_contacts = fields.Many2one(
'res.partner', string="Person", domain = [('is_company', '=', False)])
mail_contacts = fields.Char(
related = 'name_contacts.email' ,string="Email")
another_id = fields.Many2one('res.partner', string="AnotherID")
My Try: This function collects only the last set record of the field_contacts_customer_info field and puts this record in the selected_email field of every company.So it does not work right. It should collect all the mails of the field_contacts_customer_info field for every company seperated and then put them in the selected_mail field of the belonging company.
#api.onchange('field_contacts_customer_info.mail_contacts')
def compute_email(self):
list_email = []
for record in self:
if record.is_company:
for element in record.field_contacts_customer_info:
if element.name_contacts:
list_email.append(element.mail_contacts)
for email in list_email:
self.selected_email = email
Thanks.
You need to iterate over self which is a record set and loop over field_contacts_customer_info field to get mail_contacts field values.
#api.depends('field_contacts_customer_info.mail_contacts')
def get_email(self):
for record in self:
record.selected_email = ','.join(info.mail_contacts for info in record.field_contacts_customer_info if info.mail_contacts)
Then set the compute attribute to get_email:
selected_email = fields.Char(string="Mail4Info", compute='get_email')
You can check the ORM documentation on how to use the computed fields.
Edit (compute method):
You are setting the value of selected_email to each element of list_email, after the compute_email is executed the value of selected_email will always be the last value of list_email.
The last for loop is executed each time we loop over record.field_contacts_customer_info, it should be at the same level as the second loop.
The list_email is declared before we loop over records (it is not reset in the loop), after the first record, each record will use the email values of previous records.
When record.is_company is evaluated to False, the compute method will not assign a field value, you should see the following error:
ValueError: Compute method failed to assign {record description}.selected_email
It happens because the compute method must assign a field value
Example:
#api.depends('field_contacts_customer_info.mail_contacts')
def compute_email(self):
for record in self:
list_email = []
if record.is_company:
for element in record.field_contacts_customer_info:
if element.name_contacts:
list_email.append(element.mail_contacts)
emails = ""
for email in list_email:
emails += email + " "
record.selected_email = emails
else:
record.selected_email = ""
You can change the list_email type to a string and avoid looping again to get the field value:
Example:
#api.depends('field_contacts_customer_info.mail_contacts')
def compute_email(self):
for record in self:
list_email = ""
if record.is_company:
for element in record.field_contacts_customer_info:
if element.name_contacts:
list_email += element.mail_contacts
record.selected_email = list_email
I’ve got a QTableView based on a QSqlTableModel.
I want to filter displayed information: a user chooses one year in a combobox, and one or more perons in a multiple choices list. The QTableView data is filtered by these two widgets. My problem is that the data is correctly filtered on year, but only on the first personn selected. Other people's data are not displayed.
This is the code which creates the widget and the model, fills it, and filters it to display information in the QTableView :
self.model = QtSql.QSqlTableModel(self, self.db)
self.model.setEditStrategy(QtSql.QSqlTableModel.OnManualSubmit)
self.ui.tbv_suivtemp.setModel(self.model)
self.model.setTable("bdsuivis.t_suivprev_tablo")
self.model.select()
self.model.setHeaderData(22, QtCore.Qt.Horizontal, "Annee")
self.model.setHeaderData(21, QtCore.Qt.Horizontal, "Salarie")
annee = self.ui.cbx_channee.itemText(self.ui.cbx_channee.currentIndex())
if len(annee) == 0 and len(self.text_sal) == 0:
self.model.setFilter("")
else:
filtre = "annee = '%s' AND salaries IN ('%s')" % (annee, self.text_sal)
print filtre
self.model.setFilter(filtre)
This is the code to create self.text_sal:
def choisal(self):
list_sal = []
for item in xrange (len(self.ui.lst_salaries.selectedItems())):
salarie = self.ui.lst_salaries.selectedItems()[item].text().replace("\'","\'\'")
list_sal.append(salarie)
self.text_sal = ", ".join((str(x) for x in list_sal)).replace(",","\',\'")
print filtre gives :
annee = '2014' AND salaries IN ('Dupont Albert','Durant Hector')
Which represents the WHERE clause from a SQL query.
My problem is: the year is correctly filtered, but only for "Albert Dupont" - the data for "Hector Durant" is not displayed. If, as a user, I click for the first time on "Hector Durand", in my multiple choices list, then on "Albert Dupont", the data for "Hector Durand" in 2014 is displayed.
Is this normal behaviour for a QSqlTableModel filter? Is there a way to obtain data for the two persons?
If you take this website as an example:
http://gbgfotboll.se/information/?scr=table&ftid=51168
I am using this code to get information from the second table:
for url in urlList:
request = net.Request(url)
response = net.urlopen(request)
data = response.read()
dom = lxml.html.parse(BytesIO(data))
#all table rows
xpatheval = etree.XPathDocumentEvaluator(dom)
rows = xpatheval('//div[#id="content-primary"]/table[2]/tbody/tr')
divName = xpatheval('//*[#id="content-primary"]/h1//text()')[0]
trash, divisionName = divName.rsplit("- ")
dict[divisionName] = {}
for id,row in enumerate(rows):
columns = row.findall("td")
teamName = columns[0].find("a").text, # Lag
print teamName
teamName
playedGames = columns[1].text, # S
wins = columns[2].text,
draw = columns[3].text,
lost = columns[4].text,
dif = columns[6].text, # GM-IM
points = columns[7].text, # P - last column
dict[divisionName].update({id :{"teamName":columns[0].find("a").text, "playedGames":playedGames, "wins":wins, "draw":draw, "lost":lost, "dif":dif, "points":points }})
For that website the rows has table[2]
For this website:
http://gbgfotboll.se/serier/?scr=table&ftid=57108
the rows would need to look like this:
rowss = '//div[#id="content-primary"]/table[1]/tbody/tr'[0]
So what I am asking for if there is a way to get the information I need regardless what table index the table will be at?
One way to do it would be to select by its class attribute (all 3 classes are required):
xpatheval('//div[#id="content-primary"]/table[#class="clCommonGrid clTblStandings clTblWithFullToggle"]/tbody/tr'
An alternative would be to select a child element in that table that you know is only present in that specific type of table. For example, the GM-IM header could be quite specific to that type of table, so I navigate to it and then work my way up the tree to end up with the same rows as you:
xpatheval('//div[#id="content-primary"]//tr[th="GM-IM"]/../../tbody/tr')
I have a QTableView with the following code below. It runs fine, but when I am typing the search field is always the first column, which is the number and primary key.
How can I change that the standard search field is another field, second (name) for example, even with select column on the name column or with setsort on name the standard search when typing is the first number field?
When the code is running, I can change the search column by left-clicking in the second column, but I want to achieve this programmatically.
class KL_browse(QDialog, ui_kl_browse.Ui_kl_browse):
def __init__(self):
super(KL_browse, self).__init__()
query = QSqlQuery()
query.exec_("""SELECT * FROM klanten""")
self.setupUi(self)
self.model = QSqlTableModel(self)
self.model.setTable("klanten")
self.model.setSort(1, Qt.AscendingOrder)
self.model.select()
self.tableView.setModel(self.model)
self.tableView.setSelectionMode(QTableView.SingleSelection)
self.tableView.setSelectionBehavior(QTableView.SelectRows)
# self.view.setColumnHidden(ID, True)
self.tableView.horizontalHeader().setSectionsMovable(True)
self.tableView.horizontalHeader().setDragEnabled(True)
self.tableView.horizontalHeader().setDragDropMode(QAbstractItemView.InternalMove)
self.tableView.horizontalHeader().setSortIndicator(1,0)
self.tableView.selectRow(0)
self.tableView.selectColumn(1)
You need to change the index as follows:
# index: the index of a cell in the desired column
index = tableView.model().index(0, 1)
tableView.selectionModel().setCurrentIndex(index, QItemSelectionModel.NoUpdate);