pyqt4: Making Qtableview reflect the changes after calling QStandardItem.setData - python

I'm trying to build a gui using pyqt4 and am having trouble updating fields on a Qtableview
Here's my code:
table=QTableView(myqMainWindow)
model=QStandardItemModel(0,1,table)
item1= QStandardItem("123")
model.setItem(0,0,item1)
table.setModel(model)
item1.setData("321")
Now the problem I'm facing is that the table still shows "123" at the first column. What is it that I'm missing to get the table reflect the change?

Take a closer look at setData documentation.
setData take two arguments : data and role. Unless you want to define a custom role you must specify one. In your case, you should use DisplayRole
item1.setData("321", QtCore.Qt.DisplayRole)
Alternatively, you could use setText.
item1.setText("321")

Related

Filter options provided by QSqlRelationalDelegate/QSqlRelation acourding to some WHERE close

I have a QTableView populated by QSqlRelationalTableModel.
There is a column that references another table, so when I edit/create a row, this column's editor is QCombobox which gets its data from the related table. The problem is that I want to filter the data with some predefined WHERE close on the related table.
Example:
Tables:
Person:
id, name, job_id;
Job:
id, title, salary
What I want is something like
model.setRelation(3,QSqlRelation("Job", "id", "title", "WHERE salary > 50000"))
So that the QCombobox will have only Job titles with salaries > 5000.
I cannot use QSqlQueryModel as suggested in SO question - I still need users to be able to add new data or edit existing data.
It seems that someone managed to achieve this 10 years ago by tweaking the QT source code, but my C++ is bad so I could not figure it out quite well.
Possible solutions:
The first thing that comes to mind is to implement my own QSqlRelationalDelagate and populate QCombobox in the createEditor and set appropriate values in setModelData. I will try to do it myself and report the results back here. But it seems not very clean to me.
The best way would be to Extend the functionality of the QSqlRelation or QSqlRelationalTableModel but the documentation on it seems to be not very clear. So the real question is for experienced QT/PyQT developers: How do I solve the problem this way?
Update
So filtering out the contents of the QCombobox in the createEditor of the delegate works, but it requires a database query every time the editor is created which seems a bit off. And also it was quite a mess to handle new indexes after filtering. But I still wonder about the second way of approaching the problem.

Sortable Kivy List

I'm creating a Kivy/Python app that generates a formatted report. The report itself is generated with pandas dataframes and then written to Excel. I'd like to add something to the UI that would allow users to apply custom sorting to the report.
So, for instance, if the dataframe has a "Category" field with values "Cat1", "Cat2", "Cat3", I'd like to add a feature where a user could organize those categories in a custom order.
What I'm envisioning is a list of items on the Kivy UI that a user could re-sort by dragging and dropping the items? Or, even just a simple list with an up/down arrow would suffice. I believe this is generally called a listbox, but I can't seem to find that widget in Kivy. Currently, I'm managing sorting by just having an external mapping document, but I'd like to integrate this into the app functionality instead.
Note: I'm not looking for detailed code or anything--just some ideas on what modules/widgets/approach might work here.
Any thoughts would be greatly appreciated!
Thanks
Store the data inside a list property.
Create a table out of a grid layout, on which you would like to show the content of the data list. The headers of the table would be buttons that do some sorting on the list. Each time the list changes, an on_data callback will be triggered. Use the callback to redraw the table rows.

PyQt4 QTableWidget - Filter and modify data from a mySQL database

I'm new to PyQt4 and I'm wondering how to filter QTableWidget data pulled from a MySQL database. I was using a QSqlTableModel and I could filter that data easily but I don't like to update the database through a QSqlTableModel. Essentially, I would like the QTableWidget to automatically re-populate as I type search data. I looked at an example in PyQt4 on my Windows machine called "Basic Sort/Filter Model." It does what I want, however, the example uses a QTreeView and I'm using a QTableWidget. Any help would be appreciated.
In order to filter data you need to wrap your model in a QSortFilterProxyModel. The QTableWidget uses a default model that you can't change, so to use the QSortFilterProxyModel you need to use a QTableView instead.
Here is a tutorial on how to use the QSortFilterProxyModel.

QAbstractTableModel and QComboBox together

I have a subclass of a QAbstractTableModel and I want to use QComboBox to display a dropbox for this table.
But by default it shows just the first column of my table, which is not what I want. I've tried setModelColumn to shows the column 1 instead of 0 but it did not work.
After having a look around in the internet, I've found 2 solutions:
Create another QAbstractListModel from the same data in the QAbstractTableModel
Use a QSortFilterProxyModel to hide other columns
Which is the best?
Thanks
Using setModelColumn should work. I would try to fix that. Perhaps you set the modelColumn at the wrong time, docs have this to say about it:
If set prior to populating the combo box, the pop-up view will not be affected and will show the first column (using this property's default value).
If this really doesn't work, and I'm quite sure it should, then use a QSortFilterProxyModel. This will be a lot less work and should be almost trivial.

Using custom role in QTreeView instead of DisplayRole

A simple question, (hopefully with a simple answer).
QTreeView will pass Qt.DisplayRole to the model's data function when fetching rows for display, by default.
But say I wanted to pass 'MyAwesomeTreeDisplayRole' instead of Qt.DisplayRole, what would I need to do?
I can't seem to find anything about where the view decides to use displayrole or how to override it.
Just before you ask why I want to do such awful things..
Basically, my QAbstractItemModel is intended to be usable both for a treeview (1 column) and a tableview (multiple columns, based on parent).
Using the same DisplayRole for both types of views doesn't really work, since then I'm forced to return the same data for both. This results in me only seeing the first column in the treeview when I want to return a concatenation of a couple of columns.
I think the simplest way would be to just use custom roles (TreeDisplayRole and TableDisplayRole).
Thanks in advance.
I don't know, how to do it in python, but you have to create your own delegate to render items data. Delegate is actually the object, that requests any data from indices and renders it
Note, that in common case QTreeView is able to show multiple columns, you should only have columnCount set incorrectly for top-level index
I've used QTreeView to view a simple table with many columns - it works well - you can adjust the column count by sending it the columnCountChanged signal. So I'm not sure you need to do what you are asking.
But I've used ItemDelegates too: use my_treeview.setItemDelegate() to point the treeview to your item delegate. If this subclasses QStyledItemDelegate then it doesn't need to do much work - it can mostly just pass it all through to super.
The user roles then are just agreed between your custom ItemDelegate and your ItemModel and can be anything you like as long as they are >= than QtCore.Qt.UserRole.
(Edit: Sorry, I put this in as a new answer but it's really just an elaboration on what Lol4t0 said - apart from the columnCountChanged thing)

Categories

Resources