Using below code to add Items into QFormLayout, but nothing displayed and yet no any error logs can be found.
fl1 = QFormLayout()
label = QLabel()
label.setText("HELLO")
item1 = QWidgetItem(label)
fl1.setItem(1, 0, item1)
item2 = QWidgetItem(QLineEdit())
fl1.setItem(1, 1, item2)
fl1.update()
fl1.invalidate()
Per the pyqt doc, I didn't yet find any specific note about setItem:
QFormLayout.setItem (self, int row, ItemRole role, QLayoutItem item)
The item argument has it's ownership transferred to Qt.
Sets the item in the given row for the given role to item, extending the layout with empty rows if necessary.
If the cell is already occupied, the item is not inserted and an error message is sent to the console. The item spans both columns.
Warning: Do not use this function to add child layouts or child widget items. Use setLayout() or setWidget() instead.
See also setLayout().
Please share any comments will be appreciated. Thanks!
Related
I have tried the example from the Qt for Python documentation which is here:
https://doc.qt.io/qtforpython/examples/example_widgets_itemviews_editabletreemodel.html#editable-tree-model-example
After executing the example, I added some rows and child items as below:
enter image description here
Now, I am willing to select the Country automatically so that they can be highlighted one by one from the code but not by the user.
I tried as follow:
selection_model = self.treeView.selectionModel()
selection_model.select(arg1, arg2)
Now here in select)() method requires 2 arguments. could be like below:
select(index: QModelIndex | QPersistentModelIndex, command: SelectionFlag) -> None
select(selection: QItemSelection, command: SelectionFlag) -> None
My question is, how I can create the QModelIndex or QItemSelection and SelectionFlag objects to select the item from the code?
My Second question is, if I want to change the Tree data dynamically, for example want to change City from 'Toronto' to 'Hamilton', is there any api to do that without re-drawing the whole tree?
Thank you for your help. let me know is any more details required in my question.
Got the answer from the same example that I have linked in my question.
You can select(highlight) any item within tree by using: (To select first child within the root item)
# selects root
index: QModelIndex = selection_model.currentIndex()
selection_model.setCurrentIndex(self._standard_model.index(0, 0, index), QItemSelectionModel.SelectionFlag.ClearAndSelect)
# selects first child within root
index: QModelIndex = selection_model.currentIndex()
selection_model.setCurrentIndex(self._standard_model.index(0, 0, index), QItemSelectionModel.SelectionFlag.ClearAndSelect)
And you can edit the Tree item values by code using:
index: QModelIndex = self.model.index(1, 1, QModelIndex()) # to edit value at (1, 1)
model: QAbstractItemModel = self.view.model()
model.setData(index, "[No data]", Qt.EditRole)
Each column item of QTreeWidgetItem is populated with QComboBox.
So let's say I create an QTreeWidgetItem:
tree=QtGui.QTreeWidget()
treeItem=QtGui.QTreeWidgetItem()
tree.addTopLevelItem(treeItem)
for i in range(10):
tree.setItemWidget(item, i, QtGui.QComboBox())
Now if I comment out tree.addTopLevelItem(treeItem) no comboboxes will be added to the QTreeWidgetItem. By other words, I have to add QTreeWidgetItem to Tree in order to be able to add QComboBoxes to QTreeWidgetItem. But at the time QTreeWidgetItem is created I don't know if it is going to be a topLevelItem' or if it will be added to another topLevelItem as a child item using.appendRow()` method.
Should I just go ahead and assign this item to the Tree as a topLevel and then reassign it as a child? What method should I use to make a topLevelItem a child item of another top level item?
It have many way to create data in QTreeWidget in my favorite way to create, I have use constructor of QtGui.QTreeWidgetItem to link it too root item with out using QTreeWidget.addTopLevelItem and suggest not use it.
Example like this;
myQTreeWidget = QtGui.QTreeWidget()
listsHeader = ['A', 'B', 'C']
myQTreeWidget.setHeaderItem(QtGui.QTreeWidgetItem(listsHeader))
dataQTreeWidgetItem = QtGui.QTreeWidgetItem(myQTreeWidget) # assgin QTreeWidget
for i in range(len(listsHeader)):
dataQTreeWidgetItem.setText(0, 'INDEX ' + str(i)) # Test text in column
myQTreeWidget.setItemWidget(dataQTreeWidgetItem, i, QtGui.QComboBox())
Reference : http://pyqt.sourceforge.net/Docs/PyQt4/qtreewidgetitem.html#QTreeWidgetItem-3
EDITED 0:50 7/8/2014
Add header in list.
Regards,
In my code, I've created a QTableWidget with 50 columns and 2 rows.
By executing a function, Python put in cells list's elements that I've created before. But, I don't know how to modify these cells.
For example, I want to get the current data of a cell at (x,y) and add an integer. So I've tried :
content = int(self.ui.table.item(X, Y).text()) #I've just strings in my cells
self.ui.table.item(X, Y).setText(str(content + 1)
But that part of code, don't work.
I've tried too :
a=self.ui.table.item(X,Y)
print(a.data(0).toString())
But Python return me :
'NoneType' object has no attribute 'data'
Try this,hope this will work:
val = 21 # integer value
row = X # this is your row number
self.ui.table.insertRow(row) # here you decide in which row
item = QTableWidgetItem(str(val)) # create a new Item
self.ui.table.setItem(row,Y, item)
This will override the value at X,Y index of QTableWidget cell.
if you used QtDesigner to create the user interface, particularly the tables, is probably that you have a instances problem, Qtdesigner create the table (QTablewiget) but does not create cells (QTableWidgetItem) inside the table, these is the reason that when you try to get the item X, Y you got a "noneType" object, I know its sound crazy there is 3 ways to solve these:
1st : you can create the individual items as #zeb show it
2do : fill the cell on QtDesigner with a value, with this Qtdesigner create the tables items
3th : you can crare each element you need to use on the setupUi funciton as :
item = self.table.item(X,Y)
item.setText(_translate("MainWindow", " "))
ing_scroll = Scrollbar(window1_frame1, orient=VERTICAL)
ingredients = ttk.Treeview(window1_frame1, yscrollcommand=ing_scroll.set, height=5, columns=['Ingredient', 'Amount'], show="headings")
ingredients.heading("Ingredient", text='Ingredient')
ingredients.column("Ingredient", width=7)
ingredients.heading("Amount", text='Amount')
ingredients.column("Amount", width=1)
ing_scroll.config(command=ingredients.yview)
ing_scroll.pack(side=RIGHT, fill=Y)
ingredients.pack(side=LEFT, fill='both', expand=1)
def OnRecpSelect(event):
DB = menu_combo.get()
mytable = recipe_combo.get()
ingredient_list = TKengine.pull_ingredients(DB, mytable)
# NEED TO CLEAR THE INGREDIENTS TTK:TREEVIEW OBJECT HERE!
for i in ingredient_list:
ingre = i[1]
amoun = i[2]
value = ingre,amoun
ingredients.insert('',0,values=value)
ingredient_list is a list that displays something like... ('Sugar', '1 Cup') and so on... The def is for a combobox that is selected, so what I would like is for the treeview to clear and not just keep adding more ingredients. Unfortunately I don't see a clear() method.
If theres a programmatic way of identifying what is there first (enumerating a rowcount would be good...) this is driving me nuts. I did notice in the docs that you can use the delete method, but it wants to know what the item is to delete... if I use:
ingredients.delete('',0)
I get
TclError: Item 0 not found
So I would assume it wants something like 'Sugar' as the Item...
of course its a catch 22 because if you select the combobox and want to clear the ingredients treeview, the same ingredient items are not in every recipe, so how do we know what items to delete?...
Please let me know if you need any more details... I am fairly new to working with the treeview object, but its making me want to just work with two listboxes on a canvas.
To just make the code a bit more concise and Pythonic:
map(ingredients.delete, ingredients.get_children())
When you insert an item on the tree, the insert method returns an item id. This is what you give to the delete method.
Also, given an item id (such as the root item), you can get a list of all of its children with the get_children method. If you do not give any arguments to the get_children it will return a list of all the items that belong to the root element. You can then iterate over this list to delete the items.
This is all documented in the treeview docs at docs.python.org.
I have a ttk.Treeview widget with some rows of data. How do I set the focus to and select (highlight) a specified item?
tree.focus_set()
does nothing
tree.selection_set(0)
complains that: Item 0 not found, although the widget is plainly populated with more than zero items. Trying item 1 does no better.
EDIT: to select an item, find its id, then use tree.selection_set(id). Neither tree.focus(id) nor tree.focus_set(id) appears to do anything.
Get the id of treeview item you want to highlight/select
child_id = tree.get_children()[-1] # for instance the last element in tuple
To highlight the item, use both focus() and selection_set(item_id)
tree.focus(child_id)
tree.selection_set(child_id)
Note: I haven't worked with python.
Looking at this link, the focus method with optional parameter item, should highlight the node.
If not, look at selectmode option & set it to "browse".
Come across this question when I'm looking to solve the exact same problem.
Found out this:
tree.selection_set(item) highlights the item
tree.focus(item) or tree.focus_set(item) selects the item
def mycallback(event):
_iid = treeview.identify_row(event.y)
global last_focus
if _iid != last_focus:
if last_focus:
treeview.item(last_focus, tags=[])
treeview.item(_iid, tags=['focus'])
last_focus = _iid
treeview.tag_configure('focus', background='red')
global last_focus
last_focus = None
treeview.bind("<Motion>", mycallback)
Use
tree.selection_add(item_iid)
The reason why
tree.selection_set(0) doesn't work is because 0 is not the item iid, it's the index you're referring to and Treeview is expecting an iid.