I have a peculiar issue. I have a QListWidget of 1000 QListWidgetItem. I have a search textbox that triggers the following code whenever someone starts typing in it.
QRegExp regExSearch(searchText, Qt::CaseInsensitive, QRegExp::RegExp);
for (QListWidgetItem * currIt : allItems)
{
currIt->setHidden( !(currIt->text().contains(regExSearch)) );
}
What ends up being is once my search is performed, I will have a QListWidget with 600 items hidden, and 400 shown. Whenever I click on an item, the entire list just jumps down a few rows so that my selection is not even visible on the screen.
I've confirmed that it is the setHidden that seems to be causing it. If I just highlight found rows, without hiding/showing items, the selection does not cause the list to scroll down.
As such, I am wondering what am I missing? Which function to I call, to make sure that my QListWidget does not shift whenever I select an item?
Working example below:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QListWidget>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QListWidget * myListWidget = new QListWidget();
for (int i = 0; i <= 1000; ++i)
{
QListWidgetItem * myItem = new QListWidgetItem(myListWidget);
QString text("");
for (int i = 0; i <= 100; ++i)
{
text.append("W");
}
myItem->setText(text + QString::number(i));
}
for (int i = 0; i <= 1000; ++i)
{
if (i%2)
myListWidget->item(i)->setHidden(true);
}
setCentralWidget(myListWidget);
}
MainWindow::~MainWindow()
{
delete ui;
}
I have basically replicated and isolated the issue to being horizontal scrollbars. In my original application AND in this mcve, if you select an item (for example at index 314) the list will jump down. However, if I resize the list to not have horizontal scrollbars, then it does not shift.
So now that I know the issue is with having horizontal scrollbar, I am still not sure how to go about preventing the jump from happening.
UPDATE:
I have attempted to use SIGNAL-SLOT as such:
connect(myListWidget, SIGNAL(itemClicked(QListWidgetItem*)), myListWidget,
SLOT(scrollToItem(const QListWidgetItem*,QAbstractItemView::ScrollHint)));
I have also attempted to create my own slot where I explicitly specify that the item should be visible:
void MainWindow::scrollToItem(QListWidgetItem * item)
{
std::cout << "Scrolling to item." << std::endl;
myListWidget->scrollToItem(item, QAbstractItemView::EnsureVisible);
}
However, it still jumps down and out of view! It does work if I set the ScrollHint to PositionAtCenter
! BUT, from a user experience perspective, it is not a desired behaviour to have the list shift every time they click an item (even if that item is now in the center of the screen). Do I have any other options?
QListWidgetItems
above your selected item are hidden, thereby causing the visible list to become shorter, and therefore your selected item is a shorter distance from the top, and jumps out of the visible area that you are currently scrolled to – Steve Lorimer