Qt 单击列时在Qml TableView标题中查找click事件

Qt 单击列时在Qml TableView标题中查找click事件,qt,qml,Qt,Qml,在这个示例中,我有两个静态ListModel,实际上我使用LocalStorage来填充ListModel,但为了保持简单,我添加了两个按钮来更改模型,但我想将其绑定到TableView的标题列单击事件,并且无法从尝试排序的其他示例中找出如何执行该操作,我不知道是否可以使用ListModel进行排序,我找不到任何示例,因此是否有人可以解释这一点或演示如何使用列单击事件替换按钮的示例,然后我可以使用此示例将sort by参数传递给我的LocalStorage sql语句以更新ListModel 更

在这个示例中,我有两个静态ListModel,实际上我使用LocalStorage来填充ListModel,但为了保持简单,我添加了两个按钮来更改模型,但我想将其绑定到TableView的标题列单击事件,并且无法从尝试排序的其他示例中找出如何执行该操作,我不知道是否可以使用ListModel进行排序,我找不到任何示例,因此是否有人可以解释这一点或演示如何使用列单击事件替换按钮的示例,然后我可以使用此示例将sort by参数传递给我的LocalStorage sql语句以更新ListModel

<>更新:我忘了提到我正在寻找QML/QML JavaScript解决方案,因为一些原因,我认为如果我把C++标签放在了后面,我会避免这个问题,我会用这个方法作为最后的手段,因为我决定只用QML写这个应用程序,没有C++后端,但是我现在有这个版本,因为我在如何导入为Web编写的JavaScript方面遇到了问题,与Qml JavaScript相反,Qml JavaScript是不同的

要清楚的是,我正在尝试改变模型,而不是对行进行排序,这不是一个问题,区别在于如何使用点击事件,我所要做的就是在后端更改查询的名称,这是QML JavaScript,我不希望C++解决方案的原因是因为我在Felgo做这个,但这不是一个费尔戈的测试,它工作良好的C++,但你必须建立生活与它,在现实中,这将是开源我打开GITHUB,并希望它能够工作没有C++,似乎应该有一种方式来钩住这个,鼠标确实为我工作,捕捉它甚至保持头从加载,因为它在开始时挂接并等待输入,但如果必须的话,我相信您的解决方案会起作用,然后我会接受它,很抱歉出现这种混淆,我对使用什么标记感到困惑,所以最初我只包括qml,qt被添加到其中,我认为这是一个好主意,因为这确实是一个qt问题,这只涉及QML,而不是C++,这是另一个标签,这是Felgo正在推动的趋势,它们有很好的理由,JavaScript或C/C++程序员使用起来更容易,而在没有C++后端的情况下,使用实时调试工作更快,所以现在我给出了更多的信息,当我最初认为这是一个简单的问题时,这只与Qml有关,如果不是,C++已经给出了答案,除非有更好的方法,看看我想做的就是点击标题栏,就像我想在按钮上一样,我可以把按钮嵌入到列中吗?如果是,怎么做?我找不到这样的例子,只有那些会影响文本属性的,并且会对行进行排序的,这不是我试图做的,只是更新模型

import QtQuick 2.11
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.3

import QtQuick.Window 2.11

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("TableView Sort")

    Column {
        id: column
        spacing: 9
        anchors.fill: parent

        TableView {
            id: tableView
            anchors.left: column.left
            anchors.leftMargin: 6
            anchors.right: column.right
            anchors.rightMargin: 273

            highlightOnFocus: true

            model: myListModel1

            sortIndicatorVisible: true

            TableViewColumn {
                role: "title"
                title: "Column 1"
                //width: 133
            }
            TableViewColumn {
                role: "description"
                title: "Column 2"
                //width: 166
            }
        }

        Button {
            id: button1
            text: qsTr("Model 1")
            anchors.left: column.left
            anchors.leftMargin: 6
            onClicked: {
                tableView.model = myListModel1
            }
        }

        Button {
            id: button2
            text: qsTr("Model 2")
            anchors.left: column.left
            anchors.leftMargin: 6
            onClicked: {
                tableView.model = myListModel2
            }
        }
    }

    ListModel {
        id: myListModel1

        ListElement {
            title: "Orange"
            description: "Orange is Orange"
        }
        ListElement {
            title: "Banana"
            description: "Yellow"
        }
        ListElement {
            title: "Apple"
            description: "Red"
        }
    }
    ListModel {
        id: myListModel2

        ListElement {
            title: "Apple"
            description: "Red"
        }
        ListElement {
            title: "Banana"
            description: "Yellow"
        }
        ListElement {
            title: "Orange"
            description: "Orange is Orange"
        }
    }

}

更新:这起作用了

onSortIndicatorColumnChanged: tableView.model = (sortIndicatorColumn == 0) ? myListModel1 : myListModel2
onSortIndicatorOrderChanged: tableView.model = (sortIndicatorColumn == 0) ? myListModel1 : myListModel2

谢谢您的帮助。

您可以使用代理模型对模型进行排序。但是,没有QML组件,您必须使用QSortFilterProxyModel

这很容易做到。但是,QSortFilterProxyModel不能与QML tableview一起使用。表使用角色名称显示列,代理模型将尝试按索引排序

一个简单的例子:

class SortProxyModel : public QSortFilterProxyModel
{
    Q_OBJECT

public:
    SortProxyModel(): QSortFilterProxyModel ()
    {
    }

    // Define the way you want to sort data
    bool lessThan(const QModelIndex& left, const QModelIndex& right) const
    {
        int role = sourceModel()->roleNames().key(roleName.toLocal8Bit(), 0);
        return left.data(role) < right.data(role);
    }

    Q_INVOKABLE void setSortRole(QString const& roleName) // Used to select the sort role
    {
        this->roleName = roleName; 
    }

    Q_INVOKABLE virtual void sort(int /*column*/, Qt::SortOrder order = Qt::AscendingOrder)
    {
        QSortFilterProxyModel::sort(0, order); // Always use the first column.
    }
private:
    QString roleName; // Role used to sort the model
};

这只是一个简单的示例,您应该改进代码。但是,我认为这将是一个好的开始…

我更新了我的问题,将其限制在Qml。查看C++中的排序后,我认识到TabLVIEW只有1列,所以它使用属性、AKA和名称来将属性映射到列,但是我似乎可以使用委托尝试公开点击事件,但是做排序比用查询进行模型刷新更复杂。这就是我想做的,只是更新模型,而不是对它们进行排序。感谢您提供了一个替代方案,很高兴知道,其他人可能会更喜欢这个想法。在这种情况下,将OnSortIndicator ColumnChanged和OnSortIndicator OrderChanged中的代码替换为tableView.model=SortIndicator Column==0?myListModel1:myListModel2。这很有效,谢谢,不确定如何将其标记为已接受的答案,所以我会接受你的第一个问题,所以请更新它以反映这一点,再次感谢。不要在你的问题标题中添加已解决的问题
// main.cpp
// Declare your type to use it in QML
qmlRegisterType<SortProxyModel>("SortProxyModel", 0, 1, "SortProxyModel");

// Main.qml

import SortFilterProxyModel 0.1;

TableView {
            id: tableView
            model: proxy // Use the proxy model rather than the model itself

            sortIndicatorVisible: true
            onSortIndicatorColumnChanged: { // Called when you click on the header
                if (sortIndicatorColumn == 0)  // Set the role used to sort data
                    model.setSortRole("title");
                else
                    model.setSortRole("description");
                model.sort(sortIndicatorColumn, sortIndicatorOrder)
            }
            onSortIndicatorOrderChanged: { // Called when you click on the header
                if (sortIndicatorColumn == 0) // Set the role used to sort data
                    model.setSortRole("title");
                else
                    model.setSortRole("description");
                model.sort(sortIndicatorColumn, sortIndicatorOrder)
            }

    SortProxyModel {
        id: proxy
        objectName: "proxy"
        sourceModel: myListModel1
    }