kolorowanie komórki-QtableView

0

Witajcie, piszę funkcję "szukaj" która ma znaleźć w QTableView odpowiedni podciąg i zmienić tło tej komórki. O ile samo przeszukiwanie QTableView nie sprawiło mi większego problemu to zmiana koloru komórki sprawia mi ogromy problem. Zastanawiam się przede wszystkim na koncepcją jak to miałoby działać. Czy jest możliwość dynamicznego przerysowania pojedynczej komórki. Wyczytałem, że powinienem zainteresować się QItemDelegate ale czy nie ma innego sposobu?. Innym problemem jest to, że nie ma wyświetlania tekstu który jak się domyślam powinienem napisać skoro chcę używać innego sposobu rysowania.

#include "Delegate.h"
void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const
{
    QBrush br;
    QColor color(150,75,8);
    br.setColor(color);
    painter->setBackground(br);
    painter->fillRect(option.rect, option.palette.background());
}
 
0

Ehhh Puchaczov...a nie da się użyć

model->setData(index,Qt::yellow,Qt::BackgroundRole)

??

A jak już koniecznie ma być tym painterem to tak mniej więcej:

void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option,const QModelIndex &index) const
{
   QStyleOptionViewItem o=option;
   o. palette.setColor(Qt::yellow,QPalette::Window)
   QItemDelegate::paint(painter,o,index);
}
0

chyba robię coś nie halo bo u mnie to nie działa. Próbowałem to zrobić tak:

 
void Management::on_actionFind_textChanged()
{
    int rows=ui->DatabaseView->rowHeight(0);
    int columns=ui->DatabaseView->columnWidth(0);
    //QPoint point(rows,columns);
    //wyszukiwanie tekstu QtableView
    for(int i=0; i<rows; ++i)
    {
        for(int j=0; j<columns; ++j)
        {
            //findText to moj QLineEdit z którego pobieram tekst i jeśli odnajdę podciąg w komórce pobranej z QTableView to zmieniam kolor tła komórki. Całość jest podłączona    //do kontrolki sprawdzającej czy tekst w findText zmienił się i jeżeli tak jest to odpalane jest to co w tym kodzie. 
            if((ui->DatabaseView->model()->index(i,j).data().toString().indexOf(findText->text())&&!(findText->text().isEmpty())))
            {
                //kolorowanie tła komórki
                ui->DatabaseView->model()->setData(ui->DatabaseView->model()->index(i,j), Qt::yellow, Qt::BackgroundRole);
            }
        }
    }
}

niestety, brak jakiejkolwiek reakcji, kolor nie ulega zmianie.

0

A racja,bo pewnie nigdzie nie jest zapisywane.Cóż,tak testowo przeimplementuj data na taką:

QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const
{
    if(index.isValid() && role==Qt::BackgroundRole) return Qt::yellow;
//poniżej Twoja aktualna implementacja
}

No i nie używaj tego Delegata co napisałeś.
Jak to pójdzie(a na 99% powinno) wtedy w setData będziesz musiał zapisywać gdzieś ten kolor w jakąś strukturę,ot np w mapę <QModelIndex,QColor> i zwracać jej wartości dla danego indexu i Qt::BackgroundRole'a w data().

0

http://doc.trolltech.com/latest/qt.html#ItemDataRole-enum

Qt::BackgroundRole The background brush used for items rendered with the default delegate. (QBrush)

więc lepszy by był QBrush, a nie QColor.

0

przyznam, że trochę mnie to przerasta. Mianowicie mój plik.h wygląda tak:

 
#ifndef CHANGECELLCOLOR_H
#define CHANGECELLCOLOR_H
#include <QTableView>
class myModel : public QTableView
{
    Q_OBJECT
public:
    explicit myModel(QWidget *parent=0);
    QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
private:
};
#endif // CHANGECELLCOLOR_H

natomiast plik.cpp wygląda tak:

#include "changeCellColor.h"
myModel::myModel(QWidget *parent)
{
    // jak wyczytałem w jednej książce, konstruktor mogę zostawić pusty w tym przypadku.
}
QVariant myModel::data ( const QModelIndex & index, int role ) const
{
    if(index.isValid() && role==Qt::BackgroundRole) return Qt::yellow;
    if (role == Qt::TextAlignmentRole)
    {
       return int(Qt::AlignRight | Qt::AlignVCenter);
    }
    else if (role == Qt::DisplayRole)
    {
        return QString(Qt::DisplayRole);
    }
     return QVariant();
}

w pliku wywołującym:

 
    databaseView = new myModel(this);
    setCentralWidget(DatabaseView);
    DatabaseView->show();
    DatabaseView->setEditTriggers(QAbstractItemView::AllEditTriggers);
    DatabaseView->setAlternatingRowColors(1);

takie coś mi wyszło ale z pewnością potrzebuje korekty bo nie działa ;/. Całość oczywiście się kompiluje tylko nie uzyskuje efektu o który mi chodzi.

0

O Swarogu,Welesie i Trygławie.....masz zupełnie nie tak jak trzeba.
Nie dziedziczysz QTableView tylko QAbstractTableModel.Przeimplementowujesz w tej swojej klasie co najmniej funkcje data(),rowCount() i columnCount().
Następnie używasz domyślnego kutowskiego QTableView jako view,i tworzysz instancję swojej klasy modelu.
Model ten ustawiasz owemu widokowi poprzez view->setModel(yourModel);

Generalnie,odpal assistanta i czytaj od dechy do dechy o "Model/View Programming"

EDIT:
To w takim razie data przeimplementuj tak:

QVariant myModel::data ( const QModelIndex & index, int role ) const
{
    if(index.isValid() && role==Qt::BackgroundRole) return Qt::yellow;
    else return QSqlQueryModel::data(index,role);
}
0

czy o to Ci chodziło:

QSqlQueryMyModel::QSqlQueryMyModel(QObject *parent): QSqlQueryModel(parent)
{
}
int QSqlQueryMyModel::rowCount(const QModelIndex & /* parent */) const
{
    return QSqlQueryModel::rowCount();
}
int QSqlQueryMyModel::columnCount(const QModelIndex & /* parent */) const
{
    return QSqlQueryModel::columnCount();
}
QVariant QSqlQueryMyModel::data ( const QModelIndex & index, int role ) const
{
    if(index.isValid() && role==Qt::BackgroundRole) return Qt::yellow;
    else return QSqlQueryModel::data(index,role);
}
 

to oczywiście działa, jednak ustawia takie samo tło dla wszystkich komórek...

1

O takie coś by mi chodziło pod warunkiem,że wyprowadzałbyś klasę z QAbstractTableView.Skoro robisz to z QSqlQueryModel,to te funkcje są już zaimplementowane przez twórców Qt,więc Ty już nie musisz sobie zawracać głowy.
No i taka była intencja,żeby nastawić tło na wszystkie komórki tak testowo.AAA co mi tam,zapodam Ci implementację modelu który ustawia kolor na dowolny indeks:

Class PuchaczovModel : public QSqlQueryModel
{
  QMap<QModelIndex,QColor> backgrounds;

public:
  virtual QVariant data ( const QModelIndex & item, int role = Qt::DisplayRole ) const
  {
      if(item.isValid() && role==Qt::BackgroundRole) return backgrounds.value(item);//tutaj jest mały hack polegający na wykorzystaniu zwracania default-constructed value.Jeśli jesteś początkujący mocno to zapisz to raczej jako .value(index,QColor());
      else return QSqlQueryModel::data(item,role)
  }
  virtual bool setData ( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole )
  {
     if(index.isValid() && role==Qt::BackgroundRole)
     {
        backgrounds.insert(index, value.value<QColor>());
        return true;
     }
     return false;
  }
};

Teraz instrukcja

model->setData(index,Qt::yellow,Qt::BackgroundRole);

powinna działać tak jak oczekujesz ;)

0

wielkie dzięki ale jest problem z którym nie mogę sobie poradzić:

#ifndef CHANGECELLCOLOR_H
#define CHANGECELLCOLOR_H
#include <QSqlQueryModel>
class QSqlQueryMyModel : public QSqlQueryModel
{
  Q_OBJECT
  QMap<QModelIndex,QColor> backgrounds;
  QSqlQueryModel()
  {}
public:
  QSqlQueryMyModel();
  virtual QVariant data ( const QModelIndex & item, int role = Qt::DisplayRole ) const
  {
      if(item.isValid() && role==Qt::BackgroundRole)
      {
          return backgrounds.value(item,QColor());//tutaj jest mały hack polegający na wykorzystaniu zwracania default-constructed value.Jeśli jesteś początkujący mocno to zapisz to raczej jako .value(index,QColor());
      }
      else return QSqlQueryModel::data(item,role);
  }
  virtual bool setData ( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole )
  {
     if(index.isValid() && role==Qt::BackgroundRole)
     {
         backgrounds.insert(index,value); //tutaj jest problem
         return true;
     }
     return false;
  }
};
#endif // CHANGECELLCOLOR_H
 

kompilator wyrzuca:
In member function ‘virtual bool QSqlQueryMyModel::setData(const QModelIndex&, const QVariant&, int)’:
no matching function for call to ‘QMap<QModelIndex, QColor>::insert(const QModelIndex&, const QVariant&)’

ps. sorki, że jestem taki upierdliwy ;/

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.