How to insert QPushButton into TableView and make it view/display? - qt

Sorry to have to go this way, but this question is already available and I could ask there, but no no, need a reputation of 50 first. This give me 1.
From one of the answers:
QPushButton* viewButton = new QPushButton("View");
tableView->setIndexWidget(model->index(counter,2), viewButton);
I've tried that but the button doesn't display at all in, the code works but nothing shows in the cell. Have looked at the spinbox sample and tried a pushbutton delegate -no success
I'm using a QStandardItemModel to hold the data, add the model to a QSortFilterProxyModel (for filtering purpose) that is set to tableView->setModel. Display data is no problem though not the button.

The index argument in setIndexWidget(QModelIndex const& index, QWidget*) should belong to the same model, which is set in the view. What is your variable "model" refers to? To the data holder model(which is not the model set as view's model!!!) or to the proxy-model?
A safe approach would be to call:
tableView->setIndexWidget(tableView->model()->index(counter,2), viewButton);

Related

Qt: make view to update visible data

In my program I use QTableView and QAbstractTableModel that are connected. Model doesn't contain data. When view needs data to show it calls QAbstractTableModel::data and model uses another object to get data and return. At some point data in that object is going changed. Model doesn't know what has changed so dataChanged is not called.
I need that only visible part of data (that is shown in view) goes updated. It should get new data from model. I am trying to achieve that by calling update() or repaint() functions of view but it doesn't help. I am thinking that it should call paintEvent of tableview but it is not called.
How is it possible to make view update visible part of data? I don't want to update whole data that is huge.
Your wishes brokes Qt MVC logic. But if you need workaround - you may do next call to update visible area: emit dataChanged( QModelIndex(), QModelIndex() );

QML TableView access model properties from delegate

I have a TableView for which I've defined my own itemDelegate. Now, from within this delegate I can access the value for the column using styleData.value, but I'd also need to access the other properties in this same item but I can't find how to.
I need this, because the text styling needs to change depending on some other property of the item model.
Any ideas? thanks!
There is some documentation missing. Within the item delegate you can access the following (taken from the source code of TreeView.qml):
styleData (see documentation)
model (currently not documented)
modelData (currently not documented, not sure about this but I guess it's similar to ListView)
(By the way, what's also missing in the documentation but which is useful is styleData.role. Also, the documentation of the other delegates lacks some available properties too; the best is to peek into the source code of the QML file and have a look for the Loader element which instantiates your delegate. As a plus you learn how that creepy stuff works. ;))
With model and the row/column information you can then navigate to the item data. This code depends on the type of model.
If you're using QML's ListModel, then you can use model.get: model.get(styleData.row)[styleData.role] should then work (untested since I use it rarely, please give feedback).
If you're using a C++ QAbstractItemModel or friends, the best is to add a slot to the model class which takes just the row and role name, since that's the information the TableView works with (nor with role numbers nor with columns...).
However in both cases you shouldn't use the expression in a property binding! The notification system will not work since you don't use the property system for accessing the data. According to your question, I guess you wanted to use it in a expression with binding. I don't know how to properly listen to changes in the model manually.
An alternative approach is to access the other items of the row and provide a property there. Some hints:
From within one item, you can access other items of the same row by walking the object tree up twice (first to the Loader which instantiates your component, then to the actual row) and then down twice (first to the particular child object which is a Loader, then its instantiated item). You need to know the column number you want to access (not the role name), I assume you want to access the first column (index 0):
parent.parent.children[0].item
You can provide the model data using a property in each item. Assuming a simple Text element this might be:
Text {
property variant value: styleData.value // <-- Here you make it available
// your other stuff
}
Putting them together could look like the following. In this example I assume the first row contains an integer, and if it is zero, the second column should be red.
// (within TableView)
itemDelegate: Text {
property variant value: styleData.value
text: styleData.value
color: (styleData.column == 1 && parent.parent.children[0].item.value === 0)
"red" : "black"
}
I think it's pretty easy if you read the source code of TableViewItemDelegateLoader.qml (it is a private code in qtquickcontrol)
To access any role you use use : model[your_role_name] .
For exp: model["comment"]
Faced with same problem today, this is result of my investigations (Qt 5.2.x)
If you have hard limit to TableView, there is only one correct solution - use model.get(styleData.row)["roleForStyling"] as #leemes wrote. But it will very slow if you have big amount of data in model and using, for example, proxy model for sorting/filtering.
Direct solution from #leemes answer is great, but in general case not be working, because in TableView any Item wrapped in Loader and therefore independent from parent and other items:
When some item is created (where you want to change text style)
another element (from which to receive identity) cannot yet be
created
You may not have "parent" on item creation (i.e. binding will
be broken)
In my case, the best solution for deep customise was creation of the simple wrapper for ListView. In this case you have access for complete row data in delegate without the overhead. Highlights for making component ("My own ListView as table"):
Create standalone header (Rectangle or Item) - do not use header form ListView.This make it fixed for any amount of data.
Wrap ListView to ScrollView (if you need scrollbars)
Use Clip: true property in list for make correct
Set style for highlight and set highlightFollowsCurrentItem:true in ListView
As bonus in future this may be used for make "TreeTable" :)

Qt Model-View update view?

I have a model which is updated dynamically not related to the view. Which method should be called on the view to show the current models data?
Example:
StationListModel *model = new StationListModel(dynamic_list);
QListView *view = new QListView;
view->setModel(model); //view set with empty model
view->show();
In some point in time the dynamic_list is populated with new entries via a socket connection (nothing to do with View). How to populate the view with new data?
Model must emit signals to notify views when its data changed. Choose appropriate signals depending on how exactly data is changed:
dataChanged signal forces view to update specific cells, but not to create or remove cells.
layoutAboutToBeChanged and layoutChanged signals forces view to update everything.
signals about adding or removing rows and columns forces view to update accordingly.

QT SqlQueryModel, TreeView and SortFilterProxyModel how to get selected row

I have a TreeView that is feeded by a SortFilterProxyModel that is feeded by a SqlQueryModel.
Now I want to add double click event so that an edit dialog is loaded with data from the selected row and can be edited.
But all I get is a "random" row to be loaded, it's like the TreeView current index is wrong. My guess is that the SortFilterProxyModel is messing it up, but I have no clue on how to get the right index.
This is how I set my models:
proxyModel = new SortFilterProxyModel();
treeView = new QTreeView();
treeView->setModel(proxyModel);
sqlModel = new QSqlQueryModel(this);
proxyModel->setSourceModel(sqlModel);
And this is my code that gets the wrong row:
QSqlRecord product = sqlModel->record(treeView->currentIndex().row());
I'm a newbie on QT but I've looked everywhere on the net and couldn't find an answer, so I'm hoping someone here can help me! :D
I'll leave the answer they gave me in another web:
You need to take the view's currentIndex(), which is a model index for
the sorted/filter side of the proxy model, and use the proxy model's
QSortFilterProxyModel::mapToSource() function to obtain a
corresponding model index for the source model. Then you can use that
index (if valid) to address the SQL model directly.

Subclassing QStandardItemModel to avoid QAbstractItemModel

I'm implementing a Model/View for a tree like structure, and I've decided to try the QStandardItemModel on which I want to wrap on it a specific class, (which I call here "appSpecificClass").
Basically, I want part of that class (like names, or some data), to be shown in the model, and when I change the model (in edit role, or drag and drop), I want that to have consequences on the appSpecificClass (which is, when I change a name that is showing on the model, the name on the object associated with the model's item of the appSpecificClass also changes).
So, I started from subclassing the QStandardItem by a appSpecificItem, which only has a pointer to the appSpecificClass. When I construct the appSpecificItem, the text and icons are called from appSpecificClass and everything works fine.
However, when change data from appSpecificItem, naturally it does not change the appSpecificClass, because so far I didn't found any way of interacting with the appSpecificItem's pointer via overloading a virtual function (or else)
Does anyone knows how to do this/if this is possible? What can I do such that if for instance the signal
QStandardItemModel::itemChanged ( QStandardItem * item )
is emitted, I can change a the appSpecificItem's pointer.
If not, is there any good tutorial about implementing a Model from scratch? I've tried myself some, but it is not an easy task. Ideally I would like a QStandardItemModel like model, but a little more abstraction on it (such that I can put my appSpecificClass on it).

Resources