Назад Содержание

Делегаты для ячеек таблицы

Делегаты -- это специальные классы, которые могут использоваться для управления режимами отображения или редактирования ячеек таблицы QTableView, равно как и элементов других представлений (QListView, QTreeView). В данном разделе мы определим делегатов для редактирования дат и чисел в ячейках таблицы.

В листингах . и . приведён текст программы, а на рис. показан внешний вид окна в момент ввода даты рождения.

Листинг. Делегаты (файл examples-qt/db03/db03.h)

    1 #include <QtGui>
    2 #include <QtSql>
    3 
    4 class MyModel : public QSqlQueryModel {
    5     Q_OBJECT
    6 public:
    7     MyModel(QObject *parent = 0);
    8     Qt::ItemFlags flags(const QModelIndex &index) const;
    9     QVariant data(const QModelIndex &index,
   10                   int role = Qt::DisplayRole) const;
   11     bool setData(const QModelIndex &index,
   12                  const QVariant &value, int role);
   13 private:
   14     void refresh();
   15 };
   16 
   17 //-----------------------------------------------
   18 class MyView : public QTableView {
   19     Q_OBJECT
   20 public:
   21     MyView(QWidget *parent = 0);
   22 private:
   23     virtual void resizeEvent(QResizeEvent *event);
   24 };
   25 
   26 //-----------------------------------------------
   27 class MyDSBDelegate : public QItemDelegate {
   28     Q_OBJECT
   29 public:
   30     MyDSBDelegate(double min=0.00,
   31                   double max=999999999.99,
   32                   double step=0.1,
   33                   int precision=2,
   34                   QObject *parent = 0);
   35     QWidget *createEditor(
   36                 QWidget *parent,
   37                 const QStyleOptionViewItem &option,
   38                 const QModelIndex &index) const;
   39     void setEditorData(QWidget *editor,
   40                        const QModelIndex &index) const;
   41     void setModelData(QWidget *editor,
   42                       QAbstractItemModel *model,
   43                       const QModelIndex &index) const;
   44     void updateEditorGeometry(
   45             QWidget *editor,
   46             const QStyleOptionViewItem &option,
   47             const QModelIndex &index) const;
   48 private:
   49     double m_min;
   50     double m_max;
   51     double m_step;
   52     int m_precision;
   53 };
   54 
   55 //---------------------------------------------
   56 class MyDEDelegate : public QItemDelegate {
   57     Q_OBJECT
   58 public:
   59     MyDEDelegate(bool calpopup = true,
   60                  QObject *parent = 0);
   61     QWidget *createEditor(
   62                 QWidget *parent,
   63                 const QStyleOptionViewItem &option,
   64                 const QModelIndex &index) const;
   65     void setEditorData(QWidget *editor,
   66                        const QModelIndex &index) const;
   67     void setModelData(QWidget *editor,
   68                       QAbstractItemModel *model,
   69                       const QModelIndex &index) const;
   70     void updateEditorGeometry(
   71             QWidget *editor,
   72             const QStyleOptionViewItem &option,
   73             const QModelIndex &index) const;
   74 private:
   75     bool m_calpopup;
   76 };

Листинг. Делегаты (файл examples-qt/db03/db03.cpp)

    1 // Таблица базы данных: делегаты
    2 
    3 #include <QtGui>
    4 #include <QtSql>
    5 
    6 #include "db03.h"
    7 
    8 MyModel::MyModel(QObject *parent)
    9        : QSqlQueryModel(parent) {
   10     refresh();
   11 }
   12 
   13 Qt::ItemFlags MyModel::flags(
   14         const QModelIndex &index) const {
   15 
   16     Qt::ItemFlags flags = QSqlQueryModel::flags(index);
   17     if (index.column() >= 1 && index.column() < 4)
   18         flags |= Qt::ItemIsEditable;
   19     if (index.column() == 4)
   20         flags |= Qt::ItemIsUserCheckable;
   21     return flags;
   22 }
   23 
   24 QVariant MyModel::data(
   25             const QModelIndex &index,
   26             int role) const {
   27 
   28     QVariant value = QSqlQueryModel::data(index, role);
   29 
   30     switch (role) {
   31 
   32     case Qt::DisplayRole:
   33     case Qt::EditRole:
   34         if (index.column() == 0)
   35             return value.toString().prepend(tr("№"));
   36         else if (index.column() == 2 && role == Qt::DisplayRole)
   37             return value.toDate().toString("dd.MM.yyyy");
   38         else if (index.column() == 3 && role == Qt::DisplayRole)
   39             return tr("%1")
   40                    .arg(value.toDouble(), 0, 'f', 2);
   41         else if (index.column() == 4 && role == Qt::DisplayRole)
   42             return value.toInt() != 0 ? tr("Да") : tr("Нет");
   43         else
   44             return value;
   45 
   46     case Qt::TextColorRole:
   47         if(index.column() == 1)
   48             return qVariantFromValue(QColor(Qt::blue));
   49         else
   50             return value;
   51 
   52     case Qt::TextAlignmentRole:
   53         if(index.column() == 3)
   54             return int(Qt::AlignRight | Qt::AlignVCenter);
   55         else if(index.column() == 2 || index.column() == 4)
   56             return int(Qt::AlignHCenter | Qt::AlignVCenter);
   57         else
   58             return int(Qt::AlignLeft | Qt::AlignVCenter);
   59 
   60     case Qt::FontRole:
   61         if(index.column() == 1) {
   62             QFont font = QFont("Helvetica", 10, QFont::Bold);
   63             return qVariantFromValue(font);
   64         }else
   65             return value;
   66 
   67     case Qt::BackgroundColorRole: {
   68         int a = (index.row() % 2) ? 14 : 0;
   69         if(index.column() == 0)
   70             return qVariantFromValue(QColor(220,240-a,230-a));
   71         else if(index.column() == 4)
   72             return qVariantFromValue(QColor(200,220-a,255-a));
   73         else
   74             return value;
   75     }
   76     case Qt::CheckStateRole:
   77         if (index.column() == 4)
   78             return (QSqlQueryModel::data(index).toInt() != 0) ?
   79                     Qt::Checked : Qt::Unchecked;
   80         else
   81             return value;
   82 
   83     case Qt::SizeHintRole:
   84         if (index.column() == 0)
   85             return QSize(70, 10);
   86         if (index.column() == 4)
   87             return QSize(60, 10);
   88         else
   89             return QSize(110, 10);
   90     }
   91     return value;
   92 }
   93 
   94 bool MyModel::setData(
   95             const QModelIndex &index,
   96             const QVariant &value,
   97             int /* role */) {
   98     if (index.column() < 1 || index.column() > 4)
   99         return false;
  100 
  101     QModelIndex primaryKeyIndex = QSqlQueryModel::index(
  102         index.row(), 0);
  103     int id = QSqlQueryModel::data(primaryKeyIndex).toInt();
  104 
  105     //clear(); // Если надо полностью перерисовать таблицу.
  106 
  107     bool ok;
  108     QSqlQuery query;
  109     if (index.column() == 1) {
  110         query.prepare("update employee set name = ? where id = ?");
  111         query.addBindValue(value.toString());
  112         query.addBindValue(id);
  113     }else if(index.column() == 2) {
  114         query.prepare("update employee set born = ? where id = ?");
  115         query.addBindValue(value.toDate());
  116         query.addBindValue(id);
  117     }else if(index.column() == 3) {
  118         query.prepare("update employee set salary = ? where id = ?");
  119         query.addBindValue(value.toDouble());
  120         query.addBindValue(id);
  121     }else if(index.column() == 4) {
  122         query.prepare("update employee set married = ? where id = ?");
  123         query.addBindValue(value.toInt());
  124         query.addBindValue(id);
  125     }
  126     ok = query.exec();
  127     refresh();
  128     return ok;
  129 }
  130 
  131 void MyModel::refresh() {
  132     setQuery("select * from employee");
  133 
  134     setHeaderData(0, Qt::Horizontal,
  135                   tr("Табельн.\nномер"));
  136     setHeaderData(1, Qt::Horizontal,
  137                   tr("Имя"));
  138     setHeaderData(2, Qt::Horizontal,
  139                   tr("День рождения"));
  140     setHeaderData(3, Qt::Horizontal,
  141                   tr("Зарплата"));
  142     setHeaderData(4, Qt::Horizontal,
  143                   tr("Женат/\nзамужем"));
  144 }
  145 
  146 //------------------------------------
  147 MyView::MyView(QWidget *parent)
  148       : QTableView(parent) {
  149 
  150     MyDSBDelegate *dsbd = new MyDSBDelegate(
  151         0.0, 999999.99, 0.05, 2, this);
  152     setItemDelegateForColumn(3, dsbd);
  153 
  154     MyDEDelegate *ded = new MyDEDelegate(
  155             true, this);
  156     setItemDelegateForColumn(2, ded);
  157 }
  158 
  159 void MyView::resizeEvent(QResizeEvent *event) {
  160     resizeRowsToContents();
  161     // resizeColumnsToContents();
  162     QTableView::resizeEvent(event);
  163 }
  164 
  165 //------------------------------------
  166 MyDSBDelegate::MyDSBDelegate(
  167                   double min,
  168                   double max,
  169                   double step,
  170                   int precision,
  171                   QObject *parent)
  172              : QItemDelegate(parent),
  173                m_min(min),
  174                m_max(max),
  175                m_step(step),
  176                m_precision(precision) {
  177 }
  178 
  179 QWidget *MyDSBDelegate::createEditor(
  180             QWidget *parent,
  181             const QStyleOptionViewItem& /* option */,
  182             const QModelIndex& /* index */) const {
  183     QDoubleSpinBox *editor = new QDoubleSpinBox(parent);
  184     editor->setMinimum(m_min);
  185     editor->setMaximum(m_max);
  186     editor->setDecimals(m_precision);
  187     editor->setSingleStep(m_step);
  188     editor->installEventFilter(const_cast<MyDSBDelegate*>(this));
  189     return editor;
  190 }
  191 
  192 void MyDSBDelegate::setEditorData(
  193                 QWidget *editor,
  194                 const QModelIndex &index) const {
  195     double value = index.model()->data(
  196             index, Qt::EditRole).toDouble();
  197     QDoubleSpinBox *dsb = static_cast<QDoubleSpinBox*>(editor);
  198     dsb->setValue(value);
  199 }
  200 
  201 void MyDSBDelegate::setModelData(
  202             QWidget *editor,
  203             QAbstractItemModel *model,
  204             const QModelIndex& index) const {
  205     QDoubleSpinBox *dsb = static_cast<QDoubleSpinBox*>(editor);
  206     dsb->interpretText();
  207     double value = dsb->value();
  208     model->setData(index, value);
  209 }
  210 
  211 void MyDSBDelegate::updateEditorGeometry(
  212             QWidget *editor,
  213             const QStyleOptionViewItem &option,
  214             const QModelIndex& /* index */) const {
  215     editor->setGeometry(option.rect);
  216 }
  217 
  218 //------------------------------------
  219 MyDEDelegate::MyDEDelegate(
  220                     bool calpopup,
  221                     QObject *parent)
  222             : QItemDelegate(parent),
  223               m_calpopup(calpopup) {
  224 }
  225 
  226 QWidget *MyDEDelegate::createEditor(
  227             QWidget *parent,
  228             const QStyleOptionViewItem& /* option */,
  229             const QModelIndex& /* index */) const {
  230     QDateEdit *editor = new QDateEdit(parent);
  231     editor->setCalendarPopup(m_calpopup);
  232     editor->installEventFilter(const_cast<MyDEDelegate*>(this));
  233     return editor;
  234 }
  235 
  236 void MyDEDelegate::setEditorData(
  237                 QWidget *editor,
  238                 const QModelIndex &index) const {
  239     QDate value = index.model()->data(
  240             index, Qt::EditRole).toDate();
  241     QDateEdit *de = static_cast<QDateEdit*>(editor);
  242     de->setDate(value);
  243 }
  244 
  245 void MyDEDelegate::setModelData(
  246             QWidget *editor,
  247             QAbstractItemModel *model,
  248             const QModelIndex& index) const {
  249     QDateEdit *de = static_cast<QDateEdit*>(editor);
  250     de->interpretText();
  251     QDate value = de->date();
  252     model->setData(index, value);
  253 }
  254 
  255 void MyDEDelegate::updateEditorGeometry(
  256             QWidget *editor,
  257             const QStyleOptionViewItem &option,
  258             const QModelIndex& /* index */) const {
  259     editor->setGeometry(option.rect);
  260 }
  261 
  262 //------------------------------------
  263 int main(int argc, char *argv[]) {
  264 
  265     QApplication app(argc, argv);
  266 
  267     QTextCodec *codec = QTextCodec::codecForName("CP1251");
  268     QTextCodec::setCodecForTr(codec);
  269     QTextCodec::setCodecForCStrings(codec);
  270 
  271     QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
  272     db.setDatabaseName("mysql_db1");
  273     db.setUserName("");
  274     db.setPassword("");
  275     db.open();
  276 
  277     // QSqlQuery q;
  278     // q.exec(QObject::tr("SET NAMES 'cp1251'"));
  279 
  280     MyModel *model = new MyModel();
  281 
  282     MyView *view = new MyView();
  283     view->setModel(model);
  284 
  285     view->setAlternatingRowColors(true);
  286     view->resizeRowsToContents();
  287     view->resizeColumnsToContents();
  288     view->show();
  289 
  290     return app.exec();
  291 }
Назад Содержание