Qt: make view to update visible data - qt

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() );

Related

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

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);

what is the signal for qtreeview changed

There is a dictionary taken from JSON file, that is represented by QTreeView QStandardItemModel.
A user can reorganize QTreeView(add, delete, drag-n-drop) and rename items.
The goal is: call function that reads changed QTreeView, makes the dictionary and writes it to initial JSON file.
I can do it by pressing a QPushButton after changes occurred or by binding that function to every change e.g. call function when an item is deleted, call function when an item is added, call a function when an item is renamed and so on.
Is there any way to call a function if any of changes occur? Is there such a signal that corresponds to all of the mentioned changes?
The rowsMoved and itemChanged signals do what you think they do. See http://doc.qt.io/qt-4.8/qstandarditemmodel.html
As #vahancho suggests in the comments, you should connect to the layoutChanged signal. All models should emit this immedaitely after making any changes which could affect the view. So this will include sorting and filtering, as well as re-ordering, editing, deleting, etc.
The dataChanged signal is similar, but only really useful if you want to monitor specific items.

Accessing methods from another class inside a QWidget

I have a class/ QDialog (let's call it "Frame") that contains other classes. This is what it looks like:
In the above screenshot, everything inside the green rectangle is actually a separate class/custom QWidget (let's call it "Page3" since it is the third item in the list) placed inside a QStackedWidget while everything outside the rectangle is part of Frame. Everything inside the rectangle is therefore separate from Frame even though it appears to be part of the same form. Clicking the Overview and SQLite Journal objects causes a separate page to load inside the QStackedWidget. All of these classes must be able to communicate with each other.
The problem is, I’m not sure how to access Frame's public methods or variables from inside Page3. See, one of the functions of Page3 is to unlock the OK button in Frame when the contents of the two password fields (Password & Repeat) match. To do this, Page3 needs to call the method that unlocks the buttons in Frame. I need to communicate with the currently-running instance of Frame instead of creating a new copy so instantiating Frame from inside Page3 doesn't work. I can't use parent() either because that simply refers to the QStackedWidget inside Frame instead of Frame itself.
I'd appreciate it if someone could tell me how to do this.
I prefer to do this kind of thing (communication between a child widget and its parent) using signals and slots. Why? Because if the child depends explicitly on the parent, you end up with a circular dependency, and it's harder to change your design in the future.
The simplest solution is to have Page3 emit an "unlockOk" signal which is connected to a slot in Frame which does the actual "unlocking" of the button. Frame could connect the signal and slot in its constructor, or wherever else it's actually instantiating the Page3 object.
If you want to take it a step further, you could make the signals more generic; for example, signals called "inputValid" (which would be emitted when the password fields match) and "inputInvalid", which would be connected to "unlockOk" and "lockOk" slots. The reason for doing this is that you could re-use the signals in other parts of your application if you need to, and their names clearly indicate what they're communicating.

Populating a QComboBox and a QTable[View|Widget] from javascript

I'm trying to write a script for an application developed with Qt, using javascript for the business logic and a .ui file for the GUI, but I'm facing two problems.
In the ui I declared a QComboBox, to which I successfully connect javascript functions to handle
signals such as editTextChanged, etc. I was wondering I cannot populate the combobox from within
javascript code, because the addItem function is not exposed to script-side code.
combobox.editTextChanged[action](ComboBoxChanged); // OK (action is "connect" or "disconnect")
combobox.addItem("element 1"); // Error!
Is there any (other) way to do this?
I need to show a set of items (strings) in a table-like component. I tried using a QTableView and
QTableWidget but I cannot insert or get items. For example, from javascript I cannot access the
setModel function of a QTableView (if at least I could create a QAbstractItemModel from
script...), neither I can access the item(row,col) function of a QTableWidget class, to set an
item's text. Is there any way to show a table of strings to the user, let edit them and retrieve
the modified contents?
Thanks in advance.
Antonio
Because the addItem() function isn't a slot, you'll need an intermediate public slot to handle the transaction. It'll be the same with the other functions you are trying to get at as well.

In Qt, create a table with an blank editable row

This is a Qt-specific question.
It's convenient to be able to add new data to a table by typing content into a blank row at the bottom of a table. When the data is committed, a new blank row is added to the table.
Has anyone found a way of implementing this in a generic way, that fits into Qt's model-view programming architecture? My closest attempt involves creating a proxy model, such that the rowCount() returned from the model is always one greater than the source model.
QAbstractTableModel* sourceModel ; // Data is stored here
QBlankRowModel* model ; // Proxy model that adds one to rowCount()
QTableView* view ; // View
view->setModel( model ) ;
model->setSourceModel( sourceModel ) ;
Any suggestions are welcome. Thanks.
From a design-perspective, this should be part of the view, not the model. Therefore, I suggest implementing a view with the functionality and leave the model unchanged. KOffice Kexi does just this with kexitableview (screenshot, documentation). Maybe you want to use some of their code.
BTW, you might still be able to use your hack and combine it with my suggestion by putting it inside a new table view implementation YourTableView:
QBlankRowModel re-implements the
QAbstractTableModel
interface. It returns sourceModel.rowCount()+1 as the QBlankRowModel::rowCount().
It returns a QVariant() if the n+1th row is requested in QBlankRowModel::data().
All the rest within QBlankRowModel is forwarded to the sourceModel (with editing
the n+1th row in QBlankRowModel buffered and replaced with inserting into the
sourceModel when finished).
The new YourTableView inherits from
QTableView and wraps the sourceModel within
YourTableView::setModel(), calling
QTableView::setModel(QBlankRowModel(sourceModel)).
Thereby, your hack is localized at one point.
Your solutions seems a little hackish. Your problem is not only additions, it's also editions. What happens when your user edits a row, the typed data goes directly to your "data layer" even before the user commits his edition?
A better solution would be to restrict the role of your sourceModel. Rather than being a "direct" representation of your data, it should be a "buffered" representation of it. When the sourceModel is created, you make a copy of your data in some kind of Row() instances. The sourceModel, having its own copy of the data can then freely play around, perform editions and additions, and only commit the data to your model layer when the user commits his edits.
If you want a PyQt example of such a table, you can look at the source of a project of mine:
http://hg.hardcoded.net/moneyguru/
You might have to dig around to actually find the "buffering" logic because it's not in the PyQt code itself, but rather the "cross-platform" part of the code:
http://hg.hardcoded.net/moneyguru/src/tip/core/gui/table.py
This logic is then used in my QAbstractItemModel subclass:
http://hg.hardcoded.net/moneyguru/src/tip/qt/controller/table.py
Sounds like a reasonable solution, as it should work for any model that you might want as the actual table model, ie. SqlTableModel or just a plain one. As long as you add the row when the user is done editing and take care not to add the row when the user did not add any data.

Resources