2016-08-31 11 views
2

Qt5でSQLiteデータベースのGUIを開発しています。私はQSqlQueryModelQTableViewを使ってデータを保存して表示します。Qt5サブクラス化QStyledItemDelegate書式設定

次に、switch文を使用して、特定の列の数値をリテラル(たとえば1 = "Hello"、2 = "World")に置き換えるカスタムデリゲートを作成しました。

デリゲートはデータを必要に応じて表示し、機能的に機能します。ただし、カスタムデリゲートがペイントする列は、デフォルトのペイント方法であるQStyledItemDelegateとは異なる形式です。値は中央の左上ではなく左上に表示され、変更された列は自動的に列を展開して完全な値を表示しなくなり、選択された列のセルは青色に変わらず点線で囲まれません。

私は、この例のプログラム作成:これはpainter->drawText()options.displayAlignmentを追加することによって、テキストの配置を修正し

#include <QApplication> 
#include <QModelIndex> 
#include <QPainter> 
#include <QStandardItemModel> 
#include <QStyledItemDelegate> 
#include <QTableView> 


class TestDelegate: public QStyledItemDelegate { 

    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) 
     const Q_DECL_OVERRIDE 
    { 
     if (index.column() == 0) { 
      int value = index.model()->data(index, Qt::DisplayRole).toInt(); 
      QString str; 
      switch (value) { 
      case 1: 
       str = "Hello0000"; 
       break; 
      case 2: 
       str = "World0000"; 
       break; 
      } 
      if (option.state.testFlag (QStyle::State_Selected)) { 
       painter->fillRect(option.rect, option.palette.highlight()); 
       qApp->style()->drawItemText(painter, option.rect, option.displayAlignment, option.palette, true, str, QPalette::HighlightedText); 
      } else { 
       painter->drawText(option.rect, option.displayAlignment, str); 
      } 
     } else { 
      return QStyledItemDelegate::paint(painter, option, index); 
     } 
    } 

}; 


int main(int argc, char **argv) { 
    QApplication app(argc, argv); 

    QStandardItemModel model(2, 2); 
    model.setHorizontalHeaderItem(0, new QStandardItem(QString("A"))); 
    model.setHorizontalHeaderItem(1, new QStandardItem(QString("B"))); 
    model.setData(model.index(0, 0, QModelIndex()), 1); 
    model.setData(model.index(1, 0, QModelIndex()), 2); 
    model.setItem(0, 1, new QStandardItem(QString("Hello"))); 
    model.setItem(1, 1, new QStandardItem(QString("World0000"))); 

    QTableView view; 
    view.setItemDelegate(new TestDelegate); 
    view.setModel(&model); 
    view.resizeColumnsToContents(); 

    view.show(); 
    app.exec(); 
} 

を。また、選択状態に従ってセルを塗りつぶす文を追加しました(if(option.state & QStyle::State_Selected))。したがって、選択されていない場合はテキストが黒、背景が青、テキストが黒になります。しかし、私はまだ列をセルの内容に合わせて拡大することも、標準のデリゲートと同様にセルの外側に点線を追加することもできません。

カスタムペイントメソッドを使用するときに、テーブルビューのデフォルトスタイルを維持する簡単な方法はありますか?

+0

デリゲートのコードを提供できますか? –

+0

あまりコードがありません。 if(index.column()== 3){// switchステートメント// painter-> drawText(option.rect、literalStr);} else {return QStyledItemDelegate:メソッドの本体内のデリゲートのペイントメソッドをオーバーライドします。 :paint(painter、option、index) – mrwolf

+0

数値の値を文字列の値に置き換えて表示するだけであれば、デフォルトの代理人を保持し、代わりにプロキシモデルを挿入することを検討しましたか? 'QIdentityProxyModel'をサブクラス化し、' data() 'メソッドをオーバーライドすることができます。 –

答えて

0

デリゲートは、むしろ迂回的で不必要な方法です。私たちはすでに要素を完全に細かく塗りつぶすという視点を持っています。それをやり直す必要はありません。変更されたデータをビューに渡すだけで済みます。したがって、ソースとビューの間にQIdentityProxyModelビューモデルを挿入します。

// https://github.com/KubaO/stackoverflown/tree/master/questions/proxy-reformat-39244309 
#include <QtWidgets> 

class RewriteProxy : public QIdentityProxyModel { 
    QMap<QVariant, QVariant> m_read, m_write; 
    int m_column; 
public: 
    RewriteProxy(int column, QObject * parent = nullptr) : 
     QIdentityProxyModel{parent}, m_column{column} {} 
    void addReadMapping(const QVariant & from, const QVariant & to) { 
     m_read.insert(from, to); 
     m_write.insert(to, from); 
    } 
    QVariant data(const QModelIndex & index, int role) const override { 
     auto val = QIdentityProxyModel::data(index, role); 
     if (index.column() != m_column) return val; 
     auto it = m_read.find(val); 
     return it != m_read.end() ? it.value() : val; 
    } 
    bool setData(const QModelIndex & index, const QVariant & value, int role) override { 
     auto val = value; 
     if (index.column() == m_column) { 
      auto it = m_write.find(value); 
      if (it != m_write.end()) val = it.value(); 
     } 
     return QIdentityProxyModel::setData(index, val, role); 
    } 
}; 

int main(int argc, char ** argv) { 
    QApplication app{argc, argv}; 
    QStandardItemModel model{2,2}; 
    model.setData(model.index(0, 0), 1); 
    model.setData(model.index(1, 0), 2); 
    model.setData(model.index(0, 1), "Zaphod"); 
    model.setData(model.index(1, 1), "Beeblebrox"); 

    RewriteProxy proxy{0}; 
    proxy.setSourceModel(&model); 
    proxy.addReadMapping(1, "Hello"); 
    proxy.addReadMapping(2, "World"); 

    QTableView ui; 
    ui.setModel(&proxy); 
    ui.show(); 
    return app.exec(); 
} 
+0

ソリューションはQSqlQueryModelでは機能しません。 "RewriteProxy :: setSourceModel(QSqlQueryModel **) 'への呼び出しに一致する関数がありません。 – mrwolf

+0

@ Krippy_MD06解決策は間違いなくどのモデルでも機能します。コンパイラは、間違ったことをあなたに伝えます。あなたのモデルは値ではなく、ポインタなので、 '&'演算子を使ってそのアドレスを取る必要はありません。盲目的にコードをコピーして、何が起こっているのか、どのようなタイプが関係しているのか、コードがどのように違うのかを理解しようとしないでください。 –

+0

私はそれを理解しようとしていますが、 "盲目的に"コピーしていませんでした。 – mrwolf