I am working on python plugins.I used PyQt4 Designer.
I want to list query result into QTreeWidget.
My code is as follows:
c = self.db.con.cursor()
self.db._exec_sql(c, "select est from bio")
for row in c.fetchall():
item_value=unicode(row[0])
top_node1 = QTreeWidgetItem(item_value)
self.treeWidget.insertTopLevelItem(0, top_node1)
The query returns the values as:
But when i list these values into QTreeWidget using above code,it is shown as below :
Only first character is shown.If i change '0' to some other number in self.treeWidget.insertTopLevelItem(0, top_node1) ,nothing appears in QTreeWidget.
How do i do it????
thanx.
If you take a look at the documentation for a QTreeWidgetItem, you will see there are a number of possible constructors for creating an instance. Though none of which it seems you are using in a way that is going to give you desirable results. The closest match to the signature you are providing is:
QTreeWidgetItem ( const QStringList & strings, int type = Type )
What this is probably doing is taking your string (I am assuming row[0] is a string because I don't know which drivers you are using) and applying it as a sequence, which would fullfill the requiremets of QStringList. Thus what you are getting is populating multiple columns of your item with each letter of your string value. If this is what you wanted, then you would n eed to tell your widget to show more columns: self.treeWidget.setColumnCount(10). But this isn't what you are looking for I am sure.
More likely what you should be trying is to create a new item, then add the value to the desired column:
item = QTreeWidgetItem()
item.setText(0, unicode(row[0]))
self.treeWidget.insertTopLevelItem(0, item)
You can use the default constructor with no arguments, set the text value of the first column to your database record field value, and then add that item to the tree. You could also build up a list of the items and add them at once:
items = []
for row in c.fetchall():
item = QTreeWidgetItem()
item.setText(0, unicode(row[0]))
items.append(item)
self.treeWidget.insertTopLevelItems(0, items)
Your first aproach could be corrected just add a list to the widgetitem not a string like this:
top_node1 = QTreeWidgetItem([item_value])
Related
Problem Statement
I'm trying to select rows of data from my QtableWidget and print them out to my console just so I can test some things, with the end goal being able to plot the data. However I can never grab the whole row of data.
Background
I have made a GUI that can embed several QTableWidgets by importing a specifically formatted CSV file. The goal is to be able to pull data from multiple rows from the same or different tables and then plot them in a side by side fashion. Where each row of data will be its own dataset and have its own plot, but there will be multiple plots on the same figure.
To complete this task I have made a window called CompareWindow that opens when a Qpushbutton called "Compare" is pressed. The window prompts the user to type in the names of the tables and the respective rows from that table they wish to plot.
After this information is submitted I have dictionary that I can reference which has saved all the QTableObjects that have been instantiated. Where the keys are the names given to the tables which are connected to their corresponding Table Object.
Problem
The two main methods I have tried to grab the row data areā¦
The first idea was using TableObject.selectRow() command I would iterate through the rows I wanted, but whenever I did this to it would return a nonetype.
The second method I tried was to iterate a given rows columns so it would fill a list one by one by appending the item values. However when I did this it only filled the list with the same number repeatedly, which was the first cell in my Qtable.
Even when I explicitly called a certain row or column I would get the same output. The output being pulled is .12, the number from the first cell in my CSV file.
Here is the code in question I'm having problems with.
def initiateMultiPlot(self, tableV, rowV, PlotV):
"""
1. Match TableName values with the key values in our TableDB
2. When we find a match look at that key's corresponding Table Object, and iterate
through that objects rows and select the rows specified by rowV
3.Call plot for those values
"""
#calls my class and creates a blank figure where eventually we will plot data on
f = CreateFigure.FigureAssembly()
print("")
for i in tableV:
"""
tableV: is list of strings that represent assigned tablenames [Table1, Table2, Table3]
rowV: is a list, containing lists representing rows from corresponding Tables the user wishes to plot.
for example [[1,2],[3,4],[1]] means rows 1,2 from table1, rows 3,4 from table2... so on
PlotV: is a string that is ethier "box" or "whisker" to tell what method to plot. Default right now
is to do a simple boxplot
"""
print("Creating table instance")
#Table Dictionary is setup so the names of the Tables (tableV) are the keys of the dictionary
#and the actual table objects are referenced by these keys
self.TableOBJ = self.TableDictionary[i]
print("Data Type for the table object is..................{}".format(type(self.TableOBJ)))
#empty list that will store our row data
self.Elements = []
try:
for rows in rowV:
for i in rows:
print("rowV value is... {}".format(rowV))
print("current row list{}".format(rows))
print("i value is {}".format(i))
print("itterating")
for j in range(self.TableOBJ.columnCount()):
print("i value is ...{}".format(i))
print("j value is .... {}".format(j))
#FIRST idea try selecting entire row of data
print("i value is ...{}".format(i))
print("j value is .... {}".format(j))
#entire row returns none-type
EntireRow = self.TableOBJ.selectRow(i)
print(EntireRow)
#selecteditems
#SECOND idea try using for loop and iterating through every value in a row
item = self.TableOBJ.itemAt(i,j)
#explicit call for (row 1, col 1) and (row 3, col 3), both which output .12
print(self.TableOBJ.itemAt(1,1).text())
print(self.TableOBJ.itemAt(3,3).text())
print("printing item...... {}".format(item))
element = item.text()
print(element)
#list of .12
self.Elements.append(element)
#elements = [self.TableOBJ.item(i, j).text() for j in range(self.TableOBJ.columnCount()) if
# self.TableOBJ.item(i, j).text() != ""]
#print(elements)
except Exception as e:
print(e)
print(self.Elements)
Here is my GitHub link containing all my files: https://github.com/Silvuurleaf/Data-Visualize-Project
The problem occurs in my file Perspective.py in the method initiateMultiPlot. The file CompareWindow.py sends a signal to my Perspective.py and is connected to initateMultiPlot. Please inquire if anything requires more in depth explanation.
According to the documentation:
QTableWidgetItem *QTableWidget::itemAt(int ax, int ay) const
Returns the item at the position equivalent to QPoint(ax, ay) in the
table widget's coordinate system, or returns 0 if the specified point
is not covered by an item in the table widget.
That is, returns the given item x and y which are graphical coordinates with respect to QTableWidget, and clearly is not what you are looking for.
You must use the item():
QTableWidgetItem *QTableWidget::item(int row, int column) const
Returns the item for the given row and column if one has been set;
otherwise returns 0.
But in your case will not work unless you do the following change:
class CreateTable(QTableWidget):
....
for j in range(0, m):
self.item = QTableWidgetItem(str(round(ValList[j], 6)))
# print("{}, {}".format(i, j))
self.setItem(i, j, self.item)
to:
class CreateTable(QTableWidget):
....
for j in range(0, m):
item = QTableWidgetItem(str(round(ValList[j], 6)))
# print("{}, {}".format(i, j))
self.setItem(i, j, item)
That is, you change your self.item to item.
The problem is that at first glance the error is rather difficult, the QTableWidget class has an item() function, but when you use the self.item statement you are replacing that call, ie when python reads that statement it will use the attribute and not the function , So you get the error:
TypeError 'xxx' object is not callable
I have a form with a table with rows containing SELECTs with _names with IDs attached, like this:
TD_list.append(TD(SELECT(lesson_reg_list, _name='lesson_reg_' + str(student[4]))))
When the form is submitted I want to extract both the student[4] value and the value held by request.vars.lesson_reg_student[4].
I've tried something like:
for item in request.vars:
if item[0:9] == "lesson_reg":
enrolment_id = int(item[10:])
code = request.vars.item
I also tried treating request.vars like a dictionary by using:
for key, value in request.vars:
if key[0:9] == "lesson_reg":
enrolment_id = int(key[10:])
code = value
but then I got 'too many values to unpack'. How do I retrieve the value of a request.vars item when the last part of its name could be any number, plus a substring of the item name itself?
Thanks in advance for helping me.
In Python, when slicing, the ending index is excluded, so your two slices should be 0:10 and 0:11. To simplify, you can also use .startswith for the first one:
for item in request.vars:
if item.startswith('lesson_reg'):
enrolment_id = int(item[11:])
code = request.vars.item
In PyQt4, How do I delete an item from the QListView\QListWidget by a name string?
def deleteItem(itemName):
item = dialog.listWidget.indexFromItem(itemName)
dialog.listWidget.takeItem(item)
This is what I've got so far, and obviously feeding string to indexFromItem is not working...
First, look for the item in listWidget using findItems:
items_list = dialog.listWidget.findItems(itemName,Qt.MatchExactly)
This will return a list of matched QListWidgetItem with itemName (which should be a list of one item if there is only one item with itemName)
Second, call dialog.listWidget.row() to find row number of your found item(s).
Finally, detele that/those item(s) using dialog.listWidget.takeItem()
So at the end you function would look like this:
def deleteItem(itemName):
items_list = dialog.listWidget.findItems(itemName,QtCore.Qt.MatchExactly)
for item in items_list:
r = dialog.listWidget.row(item)
dialog.listWidget.takeItem(r)
Again, you have to make sure there are no items with same names otherwise they would be deleted all together.
i have a query which returns me a Viewobject with all the entries i want to process. I know i can iterate over this view Object so that i can use the single entries for my purposes.
Now i want to extract only the first and the last row. The first row is no problem because i can just iterate and break the loop after the first item.
Now my question is, how to get the last element from the View.
I tried by:
for row in result_rows:
rowvalue = row[3].value
diagdata = rowvalue[models.DIAGDATA]
if models.ODOMETER in diagdata:
start_mileage = diagdata[models.ODOMETER]
start_mileage_found = True
break
row = result_rows[len(result_rows)]
rowvalue = row[3].value
diagdata = rowvalue[models.DIAGDATA]
if models.ODOMETER in diagdata:
end_mileage = diagdata[models.ODOMETER]
end_mileage_found = True
The second value i obviously wont get, because view has neither a length nor can i access the rows by a index. Has anyone an idea how to get the last element?
You might run another request but with descending=True option, so that the server will stream results in reverse order.
Or you can convert iterator to array which basically the same a iterate through all values. I'm not a python expert, but it seems like list(result_rows) will do it for you. And when you are doing len(...) it probably doing it for you implicitly. There is rows_returned method to get the number of rows without turning it to list.
Im learning how to use QTreeWidget and Im stuck adding new items to it. The QTreewidget itself is created with qtdesigner, so my idea was just to add items. eg:
tw = self.ui.treeWidget
item = QtGui.QTreeWidgetItem("TEST")
tw.addTopLevelItem(item)
But in the treewidget only appears the first letter of "TEST". Doesnt matter what I type, it always only displays the first letter and I have no idea why...
QTreeWidgetItem constructor expects a list of strings. Try this:
tw = self.ui.treeWidget
item = QtGui.QTreeWidgetItem(["TEST"])
tw.addTopLevelItem(item)
The QtGui.QTreeWidgetItem is expecting a list for different columns. You can simply wrap your text in a list
item = QtGui.QTreeWidgetItem(["TEST"])
or you can set the text for a specific column.
item = QtGui.QTreeWidgetItem()
item.setText(0, "TEST")