Results 1 to 3 of 3

Thread: Can't get Icons in vertical header with QSortFilterProxyModel

  1. #1
    Join Date
    Sep 2006
    Posts
    38
    Thanks
    5
    Thanked 3 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default Can't get Icons in vertical header with QSortFilterProxyModel

    Hello,

    I'm working on a program that reads in a text file and puts data into a QStandardItemModel attached to a QTableView. If a particular word appears in a line of text read from the file, the program will put an "X" icon in the vertical header for that particular row. I'm having a problem with this X appearing in a QSortFilterProxyModel.

    Everything works fine in standard form. However, I'm implementing filtering capability on the tableview with a 2 QLineEdit input fields above the table. I connect the two lineEdits to a filterChanged() slot and I reimplemented QSortFilterProxyModel as follows:

    mysortfilterproxymodel.h:
    Qt Code:
    1. #ifndef MYSORTFILTERPROXYMODEL_H
    2. #define MYSORTFILTERPROXYMODEL_H
    3.  
    4. #include <QSortFilterProxyModel>
    5.  
    6. class MySortFilterProxyModel : public QSortFilterProxyModel
    7. {
    8. Q_OBJECT
    9. public:
    10. explicit MySortFilterProxyModel(QObject *parent = 0);
    11. QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const;
    12.  
    13. protected:
    14. bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
    15. };
    16.  
    17. #endif // MYSORTFILTERPROXYMODEL_H
    To copy to clipboard, switch view to plain text mode 

    mysortfilterproxymodel.cpp:
    Qt Code:
    1. #include "mysortfilterproxymodel.h"
    2. #include <QIcon>
    3.  
    4. MySortFilterProxyModel::MtSortFilterProxyModel(QObject *parent) :
    5. {
    6. }
    7. bool MySortFilterProxyModel::filterAcceptsRow(int sourceRow,
    8. const QModelIndex &sourceParent) const
    9. {
    10.  
    11. QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent);
    12. QModelIndex index1 = sourceModel()->index(sourceRow, 1, sourceParent);
    13. //filtering on 2 columns
    14.  
    15. QString filt1 = filterRegExp().pattern().section("|",0,0);
    16. QString filt2 = filterRegExp().pattern().section("|",1,1);
    17.  
    18. QRegExp f1(filt1);
    19. QRegExp f2(filt2);
    20.  
    21. return (sourceModel()->data(index0).toString().contains(f1)
    22. && sourceModel()->data(index1).toString().contains(f2));
    23. }
    24.  
    25. QVariant MySortFilterProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
    26. {
    27. if (orientation == Qt::Vertical){
    28. if (role == Qt::DecorationRole)
    29. return QIcon(":MyProgram/images/x.png");
    30. return QSortFilterProxyModel::headerData(section, orientation, role);
    31. }
    32. return QSortFilterProxyModel::headerData(section, orientation, role);
    33. }
    To copy to clipboard, switch view to plain text mode 

    My filterChanged() slot is as follows:

    Qt Code:
    1. void MainWindow::filterChanged(const QString &filt)
    2. {
    3. QString toFilt = filt;
    4. QString filt1, filt2= "";
    5.  
    6. filt1 = ui->colOneFilterLineEdit->text();
    7. filt2 = ui->colTwoFilterLineEdit->text();
    8. toFilt = filt1 + "|" + filt2;
    9.  
    10. myProxyModel->setFilterFixedString(toFilt);
    11. }
    To copy to clipboard, switch view to plain text mode 

    Here is the model setup and the line of code that detects the particular word and then places the X in the vertical header:

    Qt Code:
    1. parseModel = new QStandardItemModel(0, 2, this);
    2. parseModel ->setHeaderData(0, Qt::Horizontal, "Direction");
    3. parseModel ->setHeaderData(1, Qt::Horizontal, "Street");
    4.  
    5. //filtering proxy model for parsing table model
    6. proxyModel = new MySortFilterProxyModel;
    7. proxyModel->setSourceModel(parseModel);
    8.  
    9. // ... Code to read in file line by line and parse each line into the model. If the "word" is found, set wordPresent to true ...
    10.  
    11. if (wordPresent){
    12. parseModel->setHeaderData(row,Qt::Vertical,QIcon(":MyProgram/images/x.png"),Qt::DecorationRole);
    13. }
    To copy to clipboard, switch view to plain text mode 

    The problem I'm having is that the line of code that checks for the particular word and then places an X in the vertical column works fine when there's no QSortFilterProxyModel. That is to say the X shows up fine in the vertical header. Once I attach the proxy model, the X goes away. So I did some Google searches and saw suggestions to implement QSortFilterProxyModel::headerData(), which I tried above. But this winds up placing an X on every single row as well as a row number, so I don't think I'm doing it properly. I also tried returning a QVariant() when no Vertical or DecorationRole was detected in the mysortfilterproxymodel, but that essentially erased the vertical header.

    Can anybody help me understand where I'm going wrong and provide a suggestion to right the ship??? Thanks so much!

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Can't get Icons in vertical header with QSortFilterProxyModel

    Your headerData() function (line 30) does not qualify on section (i.e. column) and simply returns the icon for every column's Qt::DecorationRole. You will need to qualify on columns that contain matches and return a null QVariant for the others.

  3. #3
    Join Date
    Sep 2006
    Posts
    38
    Thanks
    5
    Thanked 3 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default Re: Can't get Icons in vertical header with QSortFilterProxyModel

    Ok, that makes perfect sense. However, I'm having problems qualifying the headerData(). As I mentioned earlier, the program reads in lines of text and if the text contains a specific word, it places the icon in the vertical header for that particular row. This works fine without the proxy model, but disappears when using the proxy model. So in MySortFilterProxyModel::headerData(), I'm attempting to check for !isNull() as the qualifier, but still no icon gets returned.
    Qt Code:
    1. QVariant MySortFilterProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
    2. {
    3. if (orientation == Qt::Vertical){
    4. if (role == Qt::DecorationRole){
    5. if (!(sourceModel()->headerData(section,orientation,role)).isNull()){
    6. return QIcon(":MyProgram/images/x.png");
    7. }
    8. else return QVariant();
    9. }
    10. }
    11. return QSortFilterProxyModel::headerData(section, orientation, role);
    12. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. Resizing vertical header in QTableView
    By p.csakany in forum Qt Programming
    Replies: 3
    Last Post: 1st November 2010, 23:06
  2. Vertical Header For QTreeView
    By wirasto in forum Qt-based Software
    Replies: 1
    Last Post: 12th October 2010, 05:53
  3. Qtableview Vertical header order
    By Darthspawn in forum Qt Programming
    Replies: 4
    Last Post: 26th March 2010, 15:10
  4. No Sort Vertical Header
    By wirasto in forum Qt Programming
    Replies: 4
    Last Post: 1st July 2009, 10:54
  5. Replies: 3
    Last Post: 1st February 2008, 18:18

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.