QML TableView 使用 QtQuick.Controls 2 点击行
我在网上搜索了很多,但我没有找到答案,这真的很奇怪,因为我认为这是大多数人应该使用的基本功能(可能我不明白如何正确使用 TableView 与 QtQuick.Controls 2).
I've searched a lot on the net but I didn't find an answer and that's something really strange since I suppose it's a basic functionality most people should use (probably I don't understand how to correctly use TableView with QtQuick.Controls 2).
问题是:我想知道我点击了哪一行,并且我想访问该行的特定列的数据(类似于 TableView.get(row, column)).在 QtQuick.Controls 1.4 中有一些函数允许我访问行(喜欢这个),但我找不到 QtQuick.Control 2 的任何内容.也没有有用的 selection: 和 itemDelegate: .如何在QtQuick.Controls 2中实现这些东西?
Tha problem is: I would like to know on which row I clicked and I want to access data of a particular column of that row (something like TableView.get(row, column)). In QtQuick.Controls 1.4 there are functions that allow me to access the rows (like this one) but I cannot find any for QtQuick.Control 2. Also there aren't the selection: and itemDelegate: that would be useful. How can implement these things in QtQuick.Controls 2?
我正在使用带有 MinGw 的 Qt 5.15.0.我有来自数据库的数据,这些数据通过 QAbstractTableModel 传递给 QML.
I am using Qt 5.15.0 with MinGw. I have datas from a database that are passed to QML with QAbstractTableModel.
.cpp 模型
#include "archiviosqlmodel.h"
#include <QSqlRecord>
#include <QSqlError>
#include <QSqlQuery>
#include <QDebug>
ArchivioSqlModel::ArchivioSqlModel(QObject *parent) :
QAbstractTableModel(parent)
{
db_4= QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), "def.db");
db_4.setDatabaseName("def.db");
if (!db_4.isOpen())
db_4.open();
QSqlQuery query(db_4);
query.exec("CREATE TABLE IF NOT EXISTS A (ID INTEGER PRIMARY KEY AUTOINCREMENT, B INTEGER, C CHAR(5), D CHAR(5), E CHAR(5));");
query.exec("INSERT INTO A (ID, B, C, D, E) VALUES (1, 2, 'AAAAA', 'BBBBB', 'CCCCC')");
query.exec("INSERT INTO A (ID, B, C, D, E) VALUES (2, 4, 'DDDDD', 'FFFFF', 'QQQQQ')");
query.exec("INSERT INTO A (ID, B, C, D, E) VALUES (3, 5, 'EEEEE', 'GGGGG', 'HHHHH')");
model.setQuery("SELECT * FROM A", db_4);
qDebug() << "Row Count " << model.rowCount() << "Column count " << model.columnCount();
}
ArchivioSqlModel::~ArchivioSqlModel()
{
db_4.close();
}
QVariant ArchivioSqlModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if(role == Qt::DisplayRole)
{
if(orientation == Qt::Horizontal)
{
switch (section)
{
case 0:
return tr("ID");
case 1:
return tr("A");
case 2:
return tr("A");
case 3:
return tr("A");
case 4:
return tr("A");
}
}
}
return QVariant();
}
int ArchivioSqlModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return model.rowCount();
}
int ArchivioSqlModel::columnCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return model.columnCount();
}
QVariant ArchivioSqlModel::data(const QModelIndex &index, int role) const
{
QVariant value;
if (!index.isValid())
return QVariant();
if(role == Qt::DisplayRole && index.row() >= 0 && index.row() < rowCount()
&& index.column() >= 0 && index.column() < columnCount())
{
QModelIndex modelIndex = this->index(index.row(), index.column());
value = model.data(modelIndex, Qt::DisplayRole);
return value;//QString("data %1-%2").arg(index.row()).arg(index.column());
}
return QVariant();
}
.h 模型
#include <QSqlQueryModel>
class ArchivioSqlModel : public QAbstractTableModel
{
Q_OBJECT
public:
explicit ArchivioSqlModel(QObject *parent = 0);
Q_INVOKABLE QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
~ArchivioSqlModel() override;
signals:
void queryStrChanged();
public slots:
private:
const static char* COLUMN_NAMES[];
const static char* SQL_SELECT;
QSqlDatabase db_4;
QSqlQueryModel model;
QHash<int, QByteArray> m_roleNames;
};
main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.4
import Archive 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle {
id: rectangle
x: 62
y: 106
width: 200
height: 200
color: "#000022"
border.width: 0
anchors.fill:parent
Rectangle {
id: rectangleBack
x: 10
y: 406
width: 64
height: 64
color: "#000033"
radius: 20
anchors.left: parent.left
anchors.leftMargin: 10
anchors.bottom: parent.bottom
anchors.bottomMargin: 10
border.width: 2
border.color: "#ffffff"
MouseArea {
id: mouseAreaBack
anchors.fill: parent
onClicked: {
if (stackView.depth > 1)
stackView.pop()
}
onPressed: {
rectangleBack.width = 64 - 4
rectangleBack.height = 64 - 4
}
onReleased: {
rectangleBack.width = 64
rectangleBack.height = 64
}
}
}
Text {
id: textArchive
height: 25
color: "#ffffff"
text: qsTr("Datas:")
font.family: "Arial"
verticalAlignment: Text.AlignVCenter
font.bold: true
fontSizeMode: Text.Fit
horizontalAlignment: Text.AlignHCenter
anchors.right: parent.right
anchors.rightMargin: 0
anchors.left: parent.left
anchors.leftMargin: 0
anchors.top: parent.top
anchors.topMargin: 10
font.pixelSize: 14
}
ArchivioSqlModel {
id: archiviomodel
}
Rectangle {
id: rectangle1
color: "#000022"
radius: 10
border.width: 2
border.color: "#ffffff"
anchors.right: parent.right
anchors.rightMargin: 5
anchors.left: parent.left
anchors.leftMargin: 5
anchors.bottom: rectangleBack.top
anchors.bottomMargin: 10
anchors.top: textArchive.bottom
anchors.topMargin: 10
TableView {
id: tableViewid
anchors.leftMargin: 5
anchors.bottomMargin: 5
anchors.rightMargin: 5
anchors.topMargin: 5
columnWidthProvider: function (column) { return 100; }
rowHeightProvider: function (column) { return 60; }
anchors.fill: parent
topMargin: columnsHeader.implicitHeight
model: archiviomodel
ScrollBar.horizontal: ScrollBar{}
ScrollBar.vertical: ScrollBar{}
clip: true
delegate: Rectangle {
Text {
id: textId
text: display
anchors.fill: parent
anchors.margins: 10
color: 'black'
font.pixelSize: 15
verticalAlignment: Text.AlignVCenter
}
MouseArea {
anchors.fill: parent
onClicked: {
console.log("prova:" + textId.text)
}
}
}
Rectangle { // mask the headers
z: 3
color: "#000033"
y: tableViewid.contentY
x: tableViewid.contentX
width: tableViewid.leftMargin
height: tableViewid.topMargin
}
Row {
id: columnsHeader
y: tableViewid.contentY
z: 2
Repeater {
model: tableViewid.columns > 0 ? tableViewid.columns : 1
Label {
width: tableViewid.columnWidthProvider(modelData)
height: 35
text: archiviomodel.headerData(modelData, Qt.Horizontal)
color: '#ffffff'
font.pixelSize: 15
padding: 10
verticalAlignment: Text.AlignVCenter
background: Rectangle {
radius: 10
color: "#000022"
}
}
}
}
ScrollIndicator.horizontal: ScrollIndicator { }
ScrollIndicator.vertical: ScrollIndicator { }
}
}
Rectangle {
id: rectangleOpenlap
x: 10
y: 406
width: 64
height: 64
color: "#000033"
radius: 20
anchors.right: parent.right
anchors.rightMargin: 10
anchors.bottom: parent.bottom
anchors.bottomMargin: 10
border.width: 2
border.color: "#ffffff"
MouseArea {
id: mouseAreaOpenlap
anchors.fill: parent
onClicked: {
console.log("Rows")
}
onPressed: {
rectangleOpenlap.width = 64 - 4
rectangleOpenlap.height = 64 - 4
}
onReleased: {
rectangleOpenlap.width = 64
rectangleOpenlap.height = 64
}
}
}
}
}
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "archiviosqlmodel.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
qmlRegisterType<ArchivioSqlModel>("Archive", 1, 0, "ArchivioSqlModel");
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
提前致谢!
推荐答案
要从模型中访问数据,可以使用模型上下文属性和内置的 显示角色:
To access data from the model, you can use the model context property and the built-in display role:
MouseArea {
anchors.fill: parent
onClicked: {
console.log(model.display)
}
}
模型数据可以设置 以类似的方式.
Model data can be set in a similar way.
上面基本上是下面的一个更短的方式:
The above is basically a shorter way of the following:
MouseArea {
anchors.fill: parent
onClicked: {
console.log(row, column, tableViewid.model.data(tableViewid.model.index(row, column)))
}
}
上面的代码使用 index() 创建索引然后可以将其传递给 data()
The code above uses index() to create an index that can then be passed to data()
为每个 提供行和列属性委托.
如果您出于某种原因需要从委托外部从模型中获取数据,这也很有用.
This is also useful if you need to get data from the model from outside the delegate, for whatever reason.
相关文章