使行保持在QTableView中

罗杰

我正在开发一个程序来查看和编辑文件中的记录。它的特点是QTableView显示所有记录的a,QLineEdit用于搜索记录的a以及显示所选记录详细信息的一些标签:

记录查看器

有一个QAbstractTableModel用于保存数据的QSortFilterProxyModel和一个用于帮助过滤中的行的类QTableView

搜索和过滤工作正常。在搜索框中键入文本会立即过滤记录列表。但是有两件事我无法上班:

  1. 如果列表不为空,我希望始终选择一项/当前项
  2. 在搜索框中键入内容时,必须将选定的/当前项目显示在视图中

例如,当我键入“ tesla”时,该列表将为空,因为没有项目匹配。但是,一旦我退格到“ te”,“ Forester”就匹配了,我希望它被选中。第二个例子:当(在启动程序之后)我键入“ f”时,列表将缩小到8个项目,并且选择了“ Pacifica”。当我删除“ f”时,仍然选择了Pacifica,但不再位于列表的可见部分。

我已经在Pastie上发布了完整的源代码,这里是一些(希望如此)相关的代码片段。

void MainWindow::on_lineEditSearch_textChanged(const QString & text)
{
    itemProxy->setFilterFixedString(text);

    updateStatusBar();
}

void MainWindow::currentRowChangedSlot(QModelIndex const & current, QModelIndex const & /*previous*/)
{
    Car * car = 0;

    if (current.isValid())
    {
        QModelIndex sibling = current.sibling(current.row(), COLUMN_THIS);
        QVariant variant = itemProxy->data(sibling);
        car = static_cast<Car *> (variant.value<void *> ());
    }

    updateCarMake(car);
    updateCarModel(car);
}

MainWindow::MainWindow(QWidget * parent, CarItemModel * itemModel, CarSortFilterProxyModel * itemProxy) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    this->itemModel = itemModel;
    this->itemProxy = itemProxy;

    ui->setupUi(this);
    setupStatusBar();

    ui->tableView->setModel(itemProxy);

    ui->tableView->setColumnHidden(COLUMN_THIS, true);

    QItemSelectionModel * selectionModel = ui->tableView->selectionModel();

    connect(selectionModel, SIGNAL(currentRowChanged(QModelIndex const &, QModelIndex const &)),
            this, SLOT(currentRowChangedSlot(QModelIndex const &, QModelIndex const &)));

    connect(selectionModel, SIGNAL(selectionChanged(QItemSelection const &, QItemSelection const &)),
            this, SLOT(selectionChangedSlot(QItemSelection const &, QItemSelection const &)));

    ui->tableView->selectRow(0);

    ui->lineEditSearch->setFocus();

    updateStatusBar();
}

<widget class="QTableView" name="tableView">
 <property name="verticalScrollBarPolicy">
  <enum>Qt::ScrollBarAlwaysOn</enum>
 </property>
 <property name="selectionMode">
  <enum>QAbstractItemView::SingleSelection</enum>
 </property>
 <property name="selectionBehavior">
  <enum>QAbstractItemView::SelectRows</enum>
 </property>
</widget>

因此,我的问题是:如何确保始终选择一个项目并在列表的可见部分(当然,除非用户正在滚动)?

罗杰

这就是我所做的

  • 始终选择一个项目,并且
  • 搜索时使所选项目可见

该解决方案甚至更新颖,因为当从无可见项转到一些可见项时,将选择最近选择的项,而不仅仅是第一项。

首先,我向该类添加了一个QModelIndex lastModelIndex;私有成员MainWindow,并将其设置在SelectionChanged插槽中。请注意,模型索引是存储的,而不是代理索引。

void MainWindow::selectionChangedSlot(QItemSelection const & selected, QItemSelection const & /*deselected*/)
{
    if (selected.count() > 0)
    {
        QModelIndex index = selected.indexes().first();
        QModelIndex modelIndex = itemProxy->mapToSource(index);

        lastModelIndex = modelIndex;
    }
}

接下来,我添加了两种方法:ensureSelected()...

void MainWindow::ensureSelected(QItemSelectionModel * selectionModel, int const proxyCount)
{
    if (selectionModel->hasSelection())
    {
        // an item is currently selected - don't have to do anything
    }
    else if (proxyCount == 1)
    {
        // no item is currently selected, but there is exactly one item in the list - select it
        QModelIndex proxyIndex = itemProxy->index(0, 0);

        selectionModel->setCurrentIndex(proxyIndex, QItemSelectionModel::Select | QItemSelectionModel::Rows);
    }
    else if (proxyCount > 1)
    {
        // no item is currently selected, but there are several items in the list

        QModelIndex proxyIndex; // !isValid

        if (lastModelIndex.isValid())
        {
            // there's a most recently selected item - compute its index in the list
            proxyIndex = itemProxy->mapFromSource(lastModelIndex);
        }

        if (proxyIndex.isValid())
        {
            // the most recently selected item is in the list - select it
            proxyIndex =  proxyIndex.sibling(proxyIndex.row(), COLUMN_THIS);
        }
        else
        {
            // there's no most recently selected item or it is no longer in the list - select the first item
            proxyIndex = itemProxy->index(0, 0);
        }

        selectionModel->setCurrentIndex(proxyIndex, QItemSelectionModel::Select | QItemSelectionModel::Rows);
    }
    else
    {
        // There are no items in the list - cannot select anything.
    }
}

...和ensureVisible()

void MainWindow::ensureVisible(QItemSelectionModel * selectionModel)
{
    if (selectionModel->hasSelection())
    {
        const QModelIndex index = ui->tableView->currentIndex();

        ui->tableView->scrollTo(index);
        ui->tableView->selectRow(index.row());
        ui->tableView->scrollTo(index);
    }
}

看起来很奇怪,我必须打scrollTo()两次电话,否则tableView不会滚动。

这些新方法的调用方式on_lineEditSearch_textChanged()如下:

void MainWindow::on_lineEditSearch_textChanged(const QString & text)
{
    itemProxy->setFilterFixedString(text);

    QItemSelectionModel * selectionModel = ui->tableView->selectionModel();

    int modelCount = itemModel->rowCount(); // number of items in the model
    int proxyCount = itemProxy->rowCount(); // number of items in tableview

    ensureSelected(selectionModel, proxyCount);

    ensureVisible(selectionModel);

    updateStatusBar();
}

请在Pastie上找到更新的完整源代码

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

排序,但标题行保持在顶部

来自分类Dev

将工作表保持在 500 行

来自分类Dev

更改大小时,将引导程序列保持在同一行中

来自分类Dev

将浮动元素保持在表格单元格的一行中

来自分类Dev

强制将导航栏元素保持在一行中

来自分类Dev

使用dplyr将所有行保持在R中的特定值

来自分类Dev

将光标保持在vim中重复行的相同位置

来自分类Dev

通过jQuery强制将div插入容器中以保持在同一行上

来自分类Dev

如何将两个div标签垂直保持在一行中?

来自分类Dev

使用 FlowLayout 管理器将 3 个面板保持在不同的行中

来自分类Dev

如何将浮动 ul 元素保持在一行中

来自分类Dev

在 Bootstrap 中,如何将所有元素保持在同一行?

来自分类Dev

WPF中的ElasticEase动画保持在中心

来自分类Dev

将用户会话保持在phonegap中

来自分类Dev

将所有标头元素与Jquery mobile中的对齐方式保持在同一行

来自分类Dev

如何使文本水平溢出(保持在同一行)

来自分类Dev

如何使元素与溢出保持在同一行

来自分类Dev

将Stata Data Viewer保持在给定行上

来自分类Dev

将文字保持在同一行

来自分类Dev

将grep输出保持在一行上?

来自分类Dev

强制图像与文本保持在同一行

来自分类Dev

滚动时使tvOS tableview行保持在固定位置

来自分类Dev

将 DataFrame 的行索引保持在方差阈值转换

来自分类Dev

Div 对齐,使它们保持在同一行

来自分类Dev

如何使更改保持在将使用Firebase托管的fireapp中?

来自分类Dev

如何将日期保持在Markdown文件中

来自分类Dev

将事务保持在Spring Integration流中

来自分类Dev

将UISwitch的状态保持在TableViewCell中:Swift

来自分类Dev

将图片原始尺寸保持在较小的div中

Related 相关文章

热门标签

归档