单击“列”时在Qml TableView标头中查找点击事件

时间:2019-04-06 21:22:36

标签: qt qml

在此示例中,我有2个静态ListModel,实际上,我使用LocalStorage填充ListModel,但为简单起见,我添加了2个按钮来更改Models,但我想将其与TableView的Header Column click事件关联。 ,并且无法从其他尝试排序的示例中弄清楚该怎么做,我不知道是否可以使用ListModel进行排序,我找不到任何示例,因此有人可以解释一下或显示一个示例,关于如何用列单击事件替换按钮的说明,然后我可以使用它来将sort by参数传递给我的LocalStorage sql语句,以更新ListModel。

更新:我忘了提起我正在寻找Qml / Qml JavaScript解决方案,出于某种原因,我认为如果我放弃了C ++标签,我会避免这个问题,我将把此方法作为最后的手段,因为我决定只使用Qml来编写此App,而没有C ++后端,但是我现在有了那个版本,因为我在导入为Web编写的JavaScript方面存在问题,而不是Qml JavaScript,这是不一样的。

要清楚,我试图更改模型而不是对行进行排序,这些不是相同的问题,区别在于单击事件的使用方式,我要做的就是更改查询的名称在后端,即Qml JavaScript,我不想要C ++解决方案的原因是因为我在Felgo中这样做,但这不是Felgo问题,它在C ++上可以正常工作,但是您必须设置Live才能工作有了它,实际上,这将成为我打开github的源,并希望它能够在没有C ++的情况下工作,而且似乎应该有一种方法可以钩住它,而Mouse确实为我工作,捕获了它甚至不让标题加载,因为它在开始时就挂起并等待输入,但是如果必须的话,我确定您的解决方案可以工作,那么我会接受它,对这种混乱感到抱歉,对于什么感到困惑要使用的标签,所以最初我只包含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

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

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

这很容易做到。但是,QSortFilterProxyModel不能与QML表视图一起使用(您的表使用角色名称来显示列,并且代理模型将尝试对索引进行排序)。

一个简单的例子:

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
};
// 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
    }

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