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.
Related
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);
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() );
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.
I'm trying to implement QAbstractItemModel for QTreeView. I have problem with inserting rows.
I noticed that if I insert at the beginning of my application all works fine. But If I insert rows later - after some other operations (like selections etc.) new items stay invisible. Moreover QTreeView seems to doesn't work at all! Do I have to emit some signals to notify QTreeView about rows insertion?
This is my insertion method:
bool LayersModel::insertRows(int position, int count, const QModelIndex & parent)
{
LayersModelItem * parentItem = getItem(parent);
if (position > parentItem->childCount())
return false;
beginInsertRows(parent,position,position+count-1);
bool result = true;
for (;count;--count)
result &= parentItem->insertChildren(position, new LayersModelItem());
endInsertRows();
return result;
}
LayersModelItem is class with QList with its children and data.
Full code of my project (KDE libs needed) is here:
https://github.com/coder89/PhotoFramesEditor/tree/v0.0.8
To see the problem select one of blue item on main window and then right-click on it and select "Delete item". (this method is in Canvas::removeItems()) and it is completly commented - I'm desperate and I've tried to find reason of this problem... (in fact it wasn't delete anything - it adds new item).
Thanks for any help & advice!
Just a quick guess, the QT Doc for QAbstractItemModel says...
The model emits signals to indicate
changes. For example, dataChanged() is
emitted whenever items of data made
available by the model are changed.
Changes to the headers supplied by the
model cause headerDataChanged() to be
emitted. If the structure of the
underlying data changes, the model can
emit *layoutChanged() to indicate to
any attached views that they should
redisplay any items shown, taking the
new structure into account*.
So i guess, you need to emit layoutChanged() signal from your model (whenever you change the data in model) in order to update connected views.
Also read the QT docs for model view architecture, how it is implemented in QT
see if that helps, if it doesn't i will try to download your code and debug it and see, what's wrong.
Good Luck
I have an application that displays an editor for a diagram using QGraphicsScene object. I would like to create a read only version of the same dialog but have ability for user to see both at the same time.
SimScene* pScene1 = new SimScene(model); // adds model to scene
SimScene* pScene2 = new SimScene(model); // adds model to scene
QGraphicsView* pView1 = new QGraphicsView();
pView1->setScene(pScene2);
QGraphicsView* pView1 = new QGraphicsView();
pView2->setScene(pScene2);
When I create 2 instances of QGraphicsScene and use addItem on the second one it removes all the items from the first one. Does Qt support any sort of sharing of model between scenes? Is my only choice to have same scene and try to customize the view? Later one doesn't seem to work because object selection information is within the graphics items being shared so if I disable flags on them they become read only in both views. Any advice is appreciated. Thanks.
If you just want an interactive and a read-only view on your model you can use a single QGraphicsScene and 2 QGraphicsViews. You just have to call QGraphicsView::setInteractive(false) on one of them. That way you don't have to change any item flags.
I think that you're storing QSceneItems in model classes. Because of that pScene1 and pScene2 are trying to share not only the model itself, but also the scene items. This won't work because any scene item can be placed only on one scene at any given moment.
How to fix it? Make model not aware of any GUI. Let it issue changed() notifications whenever something interesting happens.
Then let each SimScene wrap model into whatever QSceneItems it wants, and process changed() notifications.
Example:
Model:
Graph,
Edge,
Vertex
GUI
SimScene,
QEdge,
QVertex,
QSimInfo,
Qbackground, and so on ...
Also, you add pScene2 twice:
...
pView1->setScene(pScene2);
...
pView2->setScene(pScene2);
And allocate memory for the same pointer twice:
QGraphicsView* pView1 = new QGraphicsView();
...
QGraphicsView* pView1 = new QGraphicsView();