Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Help! New entries to model not sorted when sorting on a column in QTableView

Help! New entries to model not sorted when sorting on a column in QTableView

Scheduled Pinned Locked Moved General and Desktop
6 Posts 2 Posters 1.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • O Offline
    O Offline
    Olangu
    wrote on last edited by
    #1

    How do I make new rows automatically sorted when added to my model?

    By default this example program sorts on column 0, descending.
    Inserting new rows (by pressing button or by ctrl+n), will always add these in the bottom, not sorted.
    Why?

    main.cpp:
    @
    #include <QApplication>

    #include "window.h"

    int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);
    Window mainWin;
    mainWin.show();
    return app.exec();
    }
    @

    window.h:
    @
    #ifndef WINDOW_H
    #define WINDOW_H

    #include <QMainWindow>

    QT_BEGIN_NAMESPACE
    class QTableView;
    class QSortFilterProxyModel;
    QT_END_NAMESPACE

    class Model;

    class Window : public QMainWindow
    {
    Q_OBJECT

    public:
    Window();

    private:
    void createToolBars();

    QTableView *_tableView;
    QSortFilterProxyModel *_sortFilterProxy;
    Model *_model;
    };

    #endif
    @

    window.cpp:
    @
    #include <QTableView>
    #include <QSortFilterProxyModel>
    #include <QAction>
    #include <QToolBar>

    #include "window.h"

    #include "model.h"

    Window::Window()
    {
    _tableView = new QTableView(this);
    _sortFilterProxy = new QSortFilterProxyModel();
    _model = new Model();

    _sortFilterProxy->setSourceModel(_model);
    _tableView->setModel(_sortFilterProxy);
    

    _tableView->setSortingEnabled(true);

    setCentralWidget(_tableView);

    QAction *insertAct = new QAction("Insert row", this);
    insertAct->setShortcuts(QKeySequence::New);
    connect(insertAct, SIGNAL(triggered()), _model, SLOT(insertRow()));
    QToolBar *toolBar = addToolBar(tr("Toolbar"));
    toolBar->addAction(insertAct);
    

    }
    @

    model.h:
    @
    #ifndef MODEL_H
    #define MODEL_H

    #include <QAbstractTableModel>

    class Model : public QAbstractTableModel
    {
    Q_OBJECT

    public:
    Model(QObject *parent = 0);

    QVariant data(const QModelIndex &index = QModelIndex(), int role = Qt::DisplayRole) const;
    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    int columnCount(const QModelIndex &parent = QModelIndex()) const;

    public slots:
    void insertRow();

    private:
    int _columns;
    int _rows;
    };

    #endif
    @

    model.cpp:
    @
    #include <QAbstractTableModel>

    #include "model.h"

    Model::Model(QObject *parent)
    : _rows(3), _columns(6), QAbstractTableModel(parent)
    { }

    QVariant Model::data(const QModelIndex &index, int role) const
    {
    if(!index.isValid())
    {
    return QVariant();
    }

    switch( role )
    {
    case Qt::DisplayRole:
        return (index.row()+1)*(index.column()+1);
    default:
        return QVariant();
    }
    

    }

    int Model::rowCount(const QModelIndex &parent) const
    {
    return _rows;
    }

    int Model::columnCount(const QModelIndex &parent) const
    {
    return _columns;
    }

    void Model::insertRow()
    {
    QAbstractItemModel::beginInsertRows(QModelIndex(), _rows, _rows);
    _rows++;
    QAbstractItemModel::endInsertRows();
    }
    @

    CMakeLists.txt:
    @
    cmake_minimum_required (VERSION 2.6)

    set(PROJECT_NAME "SortTest")
    project (${PROJECT_NAME})

    set(CMAKE_AUTOMOC ON)
    set(CMAKE_BUILD_TYPE Debug)
    set (CMAKE_C_FLAGS "-std=c99")

    #source files
    set(${PROJECT_NAME}_SOURCES
    main.cpp
    window.cpp
    model.cpp)

    #qt
    find_package(Qt4 REQUIRED)

    #project includes
    include_directories(${PROJECT_BINARY_DIR})

    #qt includes
    include(${QT_USE_FILE})
    include_directories(${QT_INCLUDE_DIR}
    ${QT_QTCORE_INCLUDE_DIR}
    ${QT_QTGUI_INCLUDE_DIR})

    #qt libraries
    set(${PROJECT_NAME}_QT_LIBRARIES
    ${QT_QTGUI_LIBRARY}
    ${QT_QTCORE_LIBRARY})

    #our program
    add_executable(${PROJECT_NAME}
    ${${PROJECT_NAME}_SOURCES})

    #linking
    target_link_libraries(${PROJECT_NAME}
    ${${PROJECT_NAME}_QT_LIBRARIES})

    @

    1 Reply Last reply
    0
    • JeroentjehomeJ Offline
      JeroentjehomeJ Offline
      Jeroentjehome
      wrote on last edited by
      #2

      Hi,
      You might want to add a reset or update of the view in your model (insertRow function). The insert/end rows is just there to 'protect' the view from reading data when you're updating you model data causing corrupt data or non existing data.

      Greetz, Jeroen

      1 Reply Last reply
      0
      • O Offline
        O Offline
        Olangu
        wrote on last edited by
        #3

        [quote author="Jeroentje@home" date="1411736618"]Hi,
        You might want to add a reset or update of the view in your model (insertRow function). The insert/end rows is just there to 'protect' the view from reading data when you're updating you model data causing corrupt data or non existing data.
        [/quote]

        But this would remove any selections and such in the view, it also will give a huge impact on preformance.

        Am I really needed to reset my complete model (think 100 000+ elements) because I want to inset a row or two? The framework can't really be this inflexible, can it?

        1 Reply Last reply
        0
        • JeroentjehomeJ Offline
          JeroentjehomeJ Offline
          Jeroentjehome
          wrote on last edited by
          #4

          Maybe the update (QModelIndex) will do the same (then only the inserted items are updated).
          No idea how the selection will respond to that though.
          Did you read the Model/View docs for that?

          Greetz, Jeroen

          1 Reply Last reply
          0
          • O Offline
            O Offline
            Olangu
            wrote on last edited by
            #5

            [quote author="Jeroentje@home" date="1411739082"]Maybe the update (QModelIndex) will do the same (then only the inserted items are updated).
            No idea how the selection will respond to that though.
            Did you read the Model/View docs for that?[/quote]

            If im not mistaken, we don't have a QModelIndex for these rows before they are inserted. I could ofcourse catch the rowsinserted signal, but that can hardly be the way this is supposed to work.

            I've read the docs but can't find my mistake, thats why I'm asking here.

            1 Reply Last reply
            0
            • O Offline
              O Offline
              Olangu
              wrote on last edited by
              #6

              emitting layoutChanged() when the row has been inserted gives me the expected behaviour. But my guess is that it is also a very heavy operation. If anyone finds another way to do it ill be very happy.

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved