Insert data in comboBox

0

I have the following code, the result of the cursor returns the correct data, the problem that the comboBox does not show, is the correct way to fill it?

print([str(x[0]) for x in cursorUsuario])
  

['1', '4', '5', '6', '9']

self.dlg.comboLote.addItems([str(x[0]) for x in cursorUsuario])

Function where I fill the comboBox

 def obtenerUsuario(self,doc):


        with open(doc, 'r') as searchfile:

                for line in searchfile:
                    if "url=https://test/ows/wfs" in line:
                        nombreConexion = line.split('\')[1]
                        nombreUsuario = nombreConexion+"\username"
                        passwordUsuario = nombreConexion+"\password"

                        for linea in searchfile:
                            if nombreUsuario in linea:
                               usuario = linea.split("=")[1]
                               usuarioSiena = usuario.rstrip()

                sqlLote = ("select lot.idLote from [inf].[Lote] lot \
                                  inner join [dbo].[Usuario] u on lot.idUsuario = u.idUsuario \
                                  where u.userName = '%s'") % \
                                    (usuario)

                self.dlg.comboLote.clear()

                cursorUsuario = connUsuario.execute(sqlLote)

                print([str(x[0]) for x in cursorUsuario])

                self.dlg.comboLote.addItems([str(x[0]) for x in cursorUsuario])

I call the function:

def run(self):

    self.dlg.comboLote.clear()


    self.obtenerUsuario("C:\Users\usuario\AppData\Roaming\QGIS\QGIS3\profiles\default\QGIS\QGIS3.ini")
    
asked by Sebastian 16.08.2018 в 00:57
source

1 answer

2

If the adapter is expected to follow the specifications of PEP 249 - Python Database API Specification , Cursor must implement the one known as iterator protocol , which means that it returns the rows of the query one by one until they are exhausted, in each iteration it generates and returns a new tuple with the content of the next row until there is none left, at which point it generates an error StopIteration .

This has a very logical reasoning, the iterators / generators are essentially lazy, they do not generate anything before they are asked. In theory, a good implementation of a database adapter should obtain rows in batches from the server, not get all the query at once with the consequent consumption of memory when having to keep stored the complete set of results simultaneously.

This would be ideal, but the truth is that it depends on the adapter and the database, there are cases in which the query is stored completely in the client (either using Python or C containers), those that are stored in the server ... This does not really matter to us for what concerns us, what you have to be clear is that when you iterate over a cursor either through a for in , fethone , fetchall or any other method that involves iterating over it (eg list(cursor) ) this is "consuming".

Your problem is actually due to the "innocent" print probably for debugging purposes:

print([str(x[0]) for x in cursorUsuario])

where you iterate over the entire cursor to generate a list that you print and leave at the mercy of the garbage collector. When you iterate again in:

self.dlg.comboLote.addItems([str(x[0]) for x in cursorUsuario])

the cursor has nothing to return because it was consumed in the previous for . We can emulate it with:

>>> cursor = iter((("a", ), ("b", ), ("c", ), ("d", )))
>>> print([row[0] for row in cursor])
['a', 'b', 'c', 'd']

>>> [row[0] for row in cursor] # Genera una lista vacía
[]

If you eliminate that print everything will be fine, keep in mind that QComboBox.addItems accepts any iterable while it contains strings, so you can simply do:

 self.dlg.comboLote.addItems(str(x[0]) for x in cursorUsuario)

If you really need a list, iterate over the cursor once and assign the list to a variable, for example:

ls = [row[0] for row in cursorUsuario]
print(ls)
self.dlg.comboLote.addItems(ls)

As a aside, you should not use the backslash on routes without escaping. The reason is that \ is used to determine escape sequences, so in "C: \ file \ registry" \r is taken as a carriage return ... Use the slash / or you can normalize it with os.path.normpath("C:\...") .

    
answered by 16.08.2018 / 04:41
source