I think this is an easy one, but I can't solve it by myself.
I'm using a TableView from QML, and from Qt with a timer I'm sending info to the TableView to generate new rows.
I want the TableView autoscroll itself and always showme the last row I add
Use
ListView.positionViewAtEnd();
to scroll to the end of list or use
ListView.positionViewAtIndex(int index, PositionMode mode)
to scroll to specified index.
Pay attention, you must call this functions only after the list was loaded (generally in Component.onCompleted)
I find an answer
TableView.positionViewAtRow( TableView.rowCount -1, ListView.End)
I used folibis/Benjamin answer but I have to do it with a TableView, I found this answer to my problem, hope it helps some one else
Related
I tried to add an object to a TableView in JavaFX. Then I saw that there is "setAll" and "addAll". So my question is what the difference between these two functions is.
That's quite simple. "setAll" removes all previous elements before the new ones are added and "addAll" does just that. It adds all the elements to the already existing ones.
How can I get the first Item/index that is visible in a ListView? I looked inside the documentation and also searched a lot on the Internet but couldn't find anything. Does anyone know how to do that?
Thank you!
You should use something like that:
ListView {
id: contacts
model: UsersModel
onContentYChanged: {
var CurrentIndexAtTop = indexAt(1, contentY)
var CurrentPropFromModel = UsersModel.get(CurrentIndexAtTop).Name
}
}
if indexAt return -1 means not found, check this if need!
contentY - it is a property of ListView, that return current position top Y-coord of ViewList window on flickable grid ListView.
see documentation for more details http://doc.qt.io/qt-5/qml-qtquick-listview.html#indexAt-method
I know this is late but for others seeking help:
You can use the member method myView.indexAt(QPoint(0,0)) to find the first index.
I've also made a snippet to find all visible indexes in a view if you need that too:
https://gist.github.com/iSplasher/8ebc42eaf9ea206b19bd
Store the selected index when it changes.
Once the model changes and the index becomes -1, you can use positionViewAtIndex to restore the right position.
Here the documentation of the method.
Otherwise, you can do the same relying on the add and remove method.
Obviously, it works as far as the index of the selected item changes.
You can also get the index of the visible item by means of the indexAt method, but I've never used it before, even though it looks easy to use.
So, you have several methods to get the index of the visible item and you can reset the view by means of the method above mentioned.
Based on iSplasher's answer, the following works when QListView has spacing and/or has scroll by pixel:
sp = view.spacing()
first = max(view.indexAt(QPoint(sp, 0)), view.indexAt(QPoint(sp, sp * 2)))
I am working in Qt4.7, and I have a QListWidget in my dialog. I have a QString that needs to match the current text in the row of this widget (the individual rows are editable). Looking at the signals associated with QListWidget, there seem to be signals for when a different index is selected but none for when the text of a the currently selected row changes. I thought currentTextChanged(QString) would do it, but it didn't. I also thought to try to connect each individual row to something, but QListWidgetItem doesn't have any built-in signals. Does anyone know of a way to do this? Thanks!
At first it seems like QListWidget::itemChanged is the way to go, but soon you run into a problem: the signal is sent for everything - inserts, changing colors, checking boxes, and anything else that "changes" the item! Predelnik pointed that out in his answer. Some people have tried to put in flags and filter everywhere by intercepting various signals to find out if editing was the actual event. It gets very messy.
There is also QAbstractItemModel::dataChanged , which would seem like a good solution. It even has a parameter "const QVector& lstRoles" so you could scan for Qt::EditRole and see if it was really edited. Alas, there's a catch - it gets called for everything just like QListWidget::itemChanged and unfortunately, for QListWidget anyway, the roles parameter is always empty when it's called (I tried it). So much for that idea...
Fortunately, there's still hope... This solution does the trick! :
http://falsinsoft.blogspot.com/2013/11/qlistwidget-and-item-edit-event.html
He uses QAbstractItemDelegate::closeEditor, but I prefer using QAbstractItemDelegate::commitData.
So make a connect like so...
connect(ui.pLstItems->itemDelegate(), &QAbstractItemDelegate::commitData, this, &MyWidget::OnLstItemsCommitData);
Then implement the slot like this...
void MyWidget::OnLstItemsCommitData(QWidget* pLineEdit)
{
QString strNewText = reinterpret_cast<QLineEdit*>(pLineEdit)->text();
int nRow = ui.pLstItems->currentRow();
// do whatever you need here....
}
Now you have a slot that gets called only when the list item's text has been edited!
I guess you need to look into the following signal:
void QListWidget::itemChanged(QListWidgetItem * item)
But be careful because it's being sent every time some property of item changed, not only text. I remember when we ran into the problem once when we changed item colors and got tons of false positive slots called because of that. If you need more fine tuning I guess it's better to write model/view classes yourself and not rely on QListWidget.
How can I autocommit data from QTableWidget, that is in editing state, when I fire some command?
Assume, that there is some grid and data in it (editable thorough delegate that fires QComboBox editor). So, one starting to select option in combo, but do not finish editing, then hit some button, that executes action, that uses data from that combo, but new choise is not committed yet :\
How can I programmatically finish editing in table?
I mean some not strict 'loop all items and finish editing' way, that I consider as bad and ugly.
OOPS: worked too much, so, haven't realised, that there could be only one pending editor at time. Question is still here.
There is a protected slot named "commitData" in the tableWidget. You can inherit from tableWidget, then add your own public method (or slot) and send a signal (or simply call commitData method) from there.
There is one problem. You'll need to provide the editor object, but tableWidget gives you no way to get the pointer you need.
If you're using your own createEditor method, you can save the pointer to the editor somewhere, where your method can get it. It's a hack, but it's the only way i know.
The current editor does not seem to be accessible from outside of the view, but its content is committed when the current model index changes. So a simple way to force a commit seems to be to call
table->setCurrentIndex (QModelIndex ())
plus restoring your previous current index afterwards if the widget is not discarded yet.
This is quite an old question but it still came up quite high on Google so just in case anyone else needs the answer QTableView has a protected method
void currentChanged(const QModelIndex ¤t, const QModelIndex &previous)
which causes the data to be commited and QTableWidget is built on QTableView so that should still work. I found this info on the Qt Forum.
what's the best way to remove a row (QTreeWidgetItem) from a QTreeWidget?
The QTreeWidget content has been set by:
myQTreeWidget->insertTopLevelItems(0, items); // items = QList<QTreeWidgetItem*>
then I remove an item from my QList "items" and I try to clear/reset the QTreeWidget
packList->clear();
packList->insertTopLevelItems(0, items);
but my app crashes here!
Suggestions?
Your problem is that calling packList->clear() deletes the tree widget items contained by the tree. (See the documentation about QTreeWidget::clear(), which includes a note about the items being removed from the tree before deleting.) You'll either need to find a way to remove the items, or not maintain a list of them separately from the tree.
On a slightly-related note, if you are trying to keep track of other data along with the tree, I'd recommend you try to use the models paradigm. In non-trivial cases, it has usually been worth my while to convert to that technique, rather than using the widgets/items.
From what this documentation says, you should be able to do it with:
packList->takeTopLevelItem(index);
Which returns removes and returns the item at the supplied index.