我有一个简单的示例项目这里,它演示了这个问题。
我已经在下面包括了我认为是相关的来源,但其余的在上面的项目链接中可用,或者我可以编辑和包含更多,如果有用的话。
我正在查看TableView文档这里。我没有看到任何提到如何支持行选择。如果我查看这里,我会看到5.15的文档,其中描述了行选择。而且,如果我查看这里,我会看到一些Quick 1行选择的文档,但这也不适用于我的情况。
对于QT5.12和Quick 2,我找不到合适的文档。
如何为我的情况支持TableView中的行选择?如何为我的情况找到正确的文档?
main.qml
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 { }
}
}发布于 2021-06-10 21:28:06
我可以选择自己的选择。所需的逻辑很简单,因为我只需要支持单个行的选择。
我的ModelItem看起来像:
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函数
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“来引用我的自定义选择角色。
我的数据函数看起来如下:
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使用这个自定义角色:
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函数是:
void
ModelList::
select( int index )
{
beginResetModel();
for ( int x = 0; x < this->mList.length(); x++ )
{
this->mList[x].selected = ( x == index );
}
endResetModel();
}当选择更改时,begin/endResetModel将导致重新绘制表。
示例项目已经更新。
对这一解决办法提出的改进建议值得欢迎。
https://stackoverflow.com/questions/67921181
复制相似问题