This a very simple problem to which I can find no solution:
This is my code:
qint32 pos = ui->twShow->verticalScrollBar()->value();
ui->twShow->blockSignals(true);
//Code for updating the contents QTableWidget twShow, this is done by erasing all cells and adding them again, in case it matters.
ui->twShow->blockSignals(false);
if (pos > 0){
ui->twShow->verticalScrollBar()->setValue(pos);
}
What I want to accomplish is simply to maintain the vertical scroll position. However the setValue function ignores the value pos (I've checked by printing the value before and after the instruction and both times its cero).
I have also tried:
QScrollBar *bar = ui->twShow->verticalScrollBar();
// Same code as before
ui->twShow->setVerticalScrollBar(bar); //This line crashes de program
However the last line crashes the program (which I've checked by commenting it, and it works fine).
Any advice would be greatly appreciated...
Thank you very much
QTableWidget * tw;
int desiredRow;
// before update
desiredRow = tw->row(tw->itemAt(1,1));
...
// update code
...
tw->scrollToItem( tw->item( desiredRow, 0),
QAbstractItemView::EnsureVisible | QAbstractItemView::PositionAtTop );
QAbstractItemView::EnsureVisible = 0.
The 'or' flag converts the result to an integer which is not allowed as parameter of the scrollToItem method. On the other hand enums are not intended to be used as combined flags.
Related
this is my first time of asking a question in stackoverflow, sorry if my english is not really good. I hope this is a good start.
I am currently trying to use my stm32's key button/ user button (i mean the one button which already included on it in buying written "key") and i want to use the button to do some project. I did some research and found the key button is on pin A0, so i labelled it to BUTTON. So i try to check if the button is functioning using this code:
on private variable section
int a; //variable declare
on while section
while (1){
a = 0
if (HAL_GPIO_ReadPin(BUTTON_GPIO_Port, BUTTON_Pin)){
a = 1;
} else {
a = 0;
}
}
i'm expecting that when i debug the code and then see the live variable, i will find that variable "a" is gonna turn into 1 when i press the key button, but it is not working as i expected. The variable "a" is still on 0 whatever i do.
im kinda desperate, please help, i appreciate all of the answer :D.
You are setting a = 0; every time around the loop. It might briefly be set to 1 if the button is pressed, but then it will be set back to zero.
Also, the compiler may well detect that the variable a is not actually used for anything, so it might just optimize out the setting of a.
Lastly, HAL_GPIO_ReadPin() can return GPIO_PIN_RESET or GPIO_PIN_SET. So you should test that it is one of those.
Try this:
volatile int a = 0; // Tell compiler not to optimize out setting of 'a'
while (1) {
// No need to set 'a' to zero here
if (HAL_GPIO_ReadPin(BUTTON_GPIO_Port, BUTTON_Pin) == GPIO_PIN_SET){
a = 1;
} else {
a = 0;
}
}
I need to iterate through the QTreeview list with buttons the way it natively does via the keyboard arrow keys. I can get it to jump to the last item with this code, but it won't iterate through the list, it just jumps to the last item.
for( int i = 0; i < ui->TList_Tree->topLevelItemCount(); ++i )
{
ui->TList_Tree->setCurrentIndex(ui->TList_Tree->currentIndex().sibling(i,0));
}
I'm sure I'm missing something simple here.
My comments above missed the rather obvious QTreeView::indexAbove and QTreeView::indexBelow. So your button that that moves the cursor down should connect to code that does something along the lines of...
QModelIndex index = ui->TList_Tree->indexBelow(ui->TList_Tree->currentIndex());
if (index.isValid())
ui->TList_Tree->setCurrentIndex(index);
Did a quick check and this appears to do what you want.
I have a QTreeView with my own model. When adding new items into the tree, some items expand or collapse. How can I preserve the expand state when modifying the tree?
Thank you, Martin.
It's quite late for the question's author but I had a similar problem and ended up here, so maybe it is worth posting a solution I came up with.
My understanding is that updating nodes is not a problem - indices are not invalidated and expansion is conserved. When you add a new node, however, the default seems to be to make the node collapsed. The fallowing small hack changes the default to expand all newly added indices:
// This is done at the point where the model is set to be used by the view
connect(&model, &QAbstractItemModel::rowsInserted,
[&](const QModelIndex &parent, int first, int last) {
for (; first <= last; ++first) {
tree_view->expand(
model.index(first, 0, parent));
}
});
In case you want to replace a node with a new version (remove it and add a new one in its place) you can use a similar approach: remember expansion by connecting to QAbstractItemModel::rowsAboutToBeRemoved and using QTreeView::isExpanded(). The state can be resored in a function/slot connected to QAbstractItemModel::rowsInserted.
I would like to share some code, but it is too long. I will explain where my problem was instead.
This is my tree structure
It is necessary to use following functions when inserting/deleting rows.
void QAbstractItemModel::beginInsertRows(const QModelIndex & parent, int first, int last);
void QAbstractItemModel::endInsertRows()
void QAbstractItemModel::beginRemoveRows(const QModelIndex & parent, int first, int last)
void QAbstractItemModel::endRemoveRows()
I found out that when inserting/deleting items A and C, it is required to use invalid model index as a parent index. An invalid model index is QModelIndex() without any parameters. At least it is what help in my case.
A simple tree model example is available here:
http://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html
I have discovered that geometry->setLineWidth(3); in the code below extends to other QML elements and can distort them, even if those other QML elements are "normal" QML elements (with no QQuickItem subclass beneath them). This seems odd to me that you could affect other elements and I wonder if it is a bug? The documentation says that this function should only affect the current element, but that is not my experience. Can anyone weigh in on why geometry->setLineWidth(3); has such unwieldy power?
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data){
QSGGeometry *geometry =
new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 2);
geometry->setDrawingMode(GL_LINES);
geometry->setLineWidth(3);
geometry->vertexDataAsPoint2D()[0].set(0, 0);
geometry->vertexDataAsPoint2D()[1].set(width(), height());
QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
material->setColor(QColor(255, 0, 0));
QSGGeometryNode *node = new QSGGeometryNode;
node->setGeometry(geometry);
node->setFlag(QSGNode::OwnsGeometry);
node->setMaterial(material);
node->setFlag(QSGNode::OwnsMaterial);
delete oldNode;
return node;
}
If I omit the line geometry->setLineWidth(3); then the problem goes away.
I think it's a bug, sort of. The implementation in gsgbatchrenderer.cpp looks like this:
if (g->drawingMode() == GL_LINE_STRIP || g->drawingMode() == GL_LINE_LOOP || g->drawingMode() == GL_LINES)
glLineWidth(g->lineWidth());
The gl functions are global on the current OpenGL context so they apply to all drawing commands, and there's nothing that sets glLineWidth back to its previous value. However, any other nodes that also are in GL_LINES mode will also set the line width when it's their turn to render. So I'm guessing the other QML elements must be rendering lines without going through this code and setting the glLineWidth themselves. If I'm right then that's the bug and those other elements need to explicitly set the width.
Can you tell us what type those other 'normal' QML elements are?
I implemented the removeRows() method according to the documentation. My data is stored in a QList. I can remove items just fine using:
bool MeasurementManager::removeRows(int row, int count, const QModelIndex &m) {
if(count > 1) {
qDebug() << "MeasurementManager: cannot remove more than one measurement";
return false;
}
beginRemoveRows(QModelIndex(), row, row+count-1);
list.removeAt(row);
endRemoveRows();
return true
}
However, when removing the last item I get the following error message, when executing beginRemoveRows():
ASSERT failure in QList<T>::at: "index out of range"
When removing the last item (leading to the crash) it obviously has to be in row 0, but as long as there are other items in the model I can remove the item in row 0 without any problems.
If I comment out the actual removal of my data like this
beginRemoveRows(QModelIndex(), row, row+count-1);
//list.removeAt(row);
endRemoveRows();
no crash occurs, so my assumption it, that something tries to access one of list's elements after the removal. However when stepping through the function the beginRemoveRows() method clearly is the culprit.
Any help where to start debugging would be appreciated!
I found the solution, my bad. I had connected to the ´selectionChanged()´ signal to a custom slot. This tried to access the recently deleted item in the table model.
I overlooked, that deselection a table item emits an selectionChanged() signal, too.
What you see is probably an artifact of code reordering introduced by optimizing the code.
Compile the code again with all optimizations disabled to avoid confusing the debugger.
Just had the same problem. Simply call reset() and remove the rows afterwards.
void QItemSelectionModel::reset() [virtual slot]
Clears the selection model. Does not emit any signals.