首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何支持Qt5.12和2的TableView中的行选择?

如何支持Qt5.12和2的TableView中的行选择?
EN

Stack Overflow用户
提问于 2021-06-10 12:30:20
回答 1查看 499关注 0票数 1

我有一个简单的示例项目这里,它演示了这个问题。

我已经在下面包括了我认为是相关的来源,但其余的在上面的项目链接中可用,或者我可以编辑和包含更多,如果有用的话。

我正在查看TableView文档这里。我没有看到任何提到如何支持行选择。如果我查看这里,我会看到5.15的文档,其中描述了行选择。而且,如果我查看这里,我会看到一些Quick 1行选择的文档,但这也不适用于我的情况。

对于QT5.12和Quick 2,我找不到合适的文档。

如何为我的情况支持TableView中的行选择?如何为我的情况找到正确的文档?

main.qml

代码语言:javascript
复制
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12

import Backend 1.0

ApplicationWindow
{
  id:      root
  visible: true

  width:  768
  height: 450

  minimumWidth:  768
  minimumHeight: 450

  property string backendReference: Backend.objectName

  TableView
  {
    id: tableView

    columnWidthProvider: function( column )
    {
      return 100;
    }

    rowHeightProvider: function( column )
    {
      return 23;
    }

    anchors.fill: parent
    topMargin:    columnsHeader.implicitHeight

    model: Backend.modelResults.list

    ScrollBar.horizontal: ScrollBar {}
    ScrollBar.vertical:   ScrollBar {}

    clip: true

    delegate: Rectangle
    {
      Text
      {
        text: display
        anchors.fill: parent
        anchors.margins: 10
        color: 'black'
        font.pixelSize: 15
        verticalAlignment: Text.AlignVCenter
      }
    }

    Rectangle // mask the headers
    {
      z: 3

      color: "#222222"

      y: tableView.contentY
      x: tableView.contentX

      width:  tableView.leftMargin
      height: tableView.topMargin
    }

    Row
    {
      id: columnsHeader
      y:  tableView.contentY

      z: 2

      Repeater
      {
        model: tableView.columns > 0 ? tableView.columns : 1

        Label
        {
          width:  tableView.columnWidthProvider(modelData)
          height: 35

          text: Backend.modelResults.list.headerData( modelData, Qt.Horizontal )

          font.pixelSize:    15
          padding:           10
          verticalAlignment: Text.AlignVCenter

          background: Rectangle
          {
            color: "#eeeeee"
          }
        }
      }
    }

    ScrollIndicator.horizontal: ScrollIndicator { }
    ScrollIndicator.vertical: ScrollIndicator { }
  }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-10 21:28:06

我可以选择自己的选择。所需的逻辑很简单,因为我只需要支持单个行的选择。

我的ModelItem看起来像:

代码语言:javascript
复制
struct ModelItem
{
    Q_GADGET

    Q_PROPERTY( QString population MEMBER population )
    Q_PROPERTY( int averageAge MEMBER averageAge )
    Q_PROPERTY( bool selected MEMBER selected )

public:

    enum class Role {
      Selection = Qt::UserRole,
      ColumnType,
      ColorValue
    };
    Q_ENUM(Role)

    QString population;
    int     averageAge;
    bool    selected    { false };

    bool operator!=( const ModelItem& other )
    {
        return other.population != this->population
            || other.averageAge != this->averageAge;
    }

};

这里的关键点是要保存的所选属性是否选择某一项,以及自定义选择角色的定义。

我需要一个自定义角色的roleNames函数

代码语言:javascript
复制
QHash<int, QByteArray>
ModelList::
roleNames() const
{
  return {
    { Qt::DisplayRole, "display" },
    { int( ModelItem::Role::Selection ), "selected" },
    { int( ModelItem::Role::ColumnType ), "type" },
    { int( ModelItem::Role::ColorValue ), "colorValue" }
  };
}

这里的关键是我使用字符串"selected“来引用我的自定义选择角色。

我的数据函数看起来如下:

代码语言:javascript
复制
QVariant
ModelList::
data( const QModelIndex& index, int role ) const
{
    const ModelItem modelItem = mList.at( index.row() );

    QVariant result = QVariant();

    if ( role == Qt::DisplayRole )
    {
        if ( index.column() == 0 )
        {
          result = QVariant( QString( modelItem.population ) );
        }
        else
        {
          result = QVariant( QString::number( modelItem.averageAge ) );
        }
    }

    if ( role == int( ModelItem::Role::Selection ) )
    {
        result = QVariant( QString( modelItem.selected ? "#eeeeee" : "white" ) );
    }

    if ( role == int( ModelItem::Role::ColumnType ) )
    {
      if ( index.column() == 0 )
        result = QVariant( QString( "stringValue" ) );
      else
        result = QVariant( QString( "colorValue" ) );
    }

    if ( role == int( ModelItem::Role::ColorValue ) )
    {
      QString color;

      if ( modelItem.averageAge < 13 )
        color = "red";
      else if ( modelItem.averageAge < 35 )
        color = "yellow";
      else
        color = "green";

      result = QVariant( color );
    }

    qDebug() << role << " " << result;

    return result;
}

这里的关键是检查角色是否是自定义选择角色,然后根据modelItem中选定的值返回颜色。

最后一部分是让QML使用这个自定义角色:

代码语言:javascript
复制
delegate: DelegateChooser
{
  role: "type"

  DelegateChoice
  {
    roleValue: "colorValue"

    delegate: Rectangle
    {
      color: selected

      Rectangle
      {
        color: colorValue

        width: parent.height
        height: parent.height

        radius: width * 0.5;

        anchors.horizontalCenter: parent.horizontalCenter;
      }

      MouseArea
      {
        anchors.fill: parent

        onClicked:
        {
          var idx = Backend.modelResults.list.index( row, column )

          console.log( "Clicked cell: ", idx.row, " ", Backend.modelResults.list.data( idx ) )

          Backend.modelResults.list.select( idx.row );
        }
      }
    }
  }

  DelegateChoice
  {
    delegate: Rectangle
    {
      color: selected

      Text
      {
        text: display
        anchors.fill: parent
        anchors.margins: 10
        color: 'black'
        font.pixelSize: 15
        verticalAlignment: Text.AlignVCenter
      }

      MouseArea
      {
        anchors.fill: parent

        onClicked:
        {
          var idx = Backend.modelResults.list.index( row, column )

          console.log( "Clicked cell: ", idx.row, " ", Backend.modelResults.list.data( idx ) )

          Backend.modelResults.list.select( idx.row );
        }
      }
    }
  }
}

这里的键是矩形的color: selected部分,用于每个DelegateChoice的委托。selected是指在上面的roleNames函数中设置的字符串selected。系统知道使用正确的ModelItem::Role调用数据函数,因此if ( role == int( ModelItem::Role::Selection ) )解析为true

对于每个DelegateChoice,我为单元格定义了一个MouseArea,该单元格调用模型中的select函数。select函数是:

代码语言:javascript
复制
void
ModelList::
select( int index )
{
  beginResetModel();

  for ( int x = 0; x < this->mList.length(); x++ )
  {
    this->mList[x].selected = ( x == index );
  }

  endResetModel();
}

当选择更改时,begin/endResetModel将导致重新绘制表。

示例项目已经更新。

对这一解决办法提出的改进建议值得欢迎。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67921181

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档