Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Spanish
  4. QPushButton delegate en QTableView
QtWS25 Last Chance

QPushButton delegate en QTableView

Scheduled Pinned Locked Moved Spanish
3 Posts 1 Posters 4.2k 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
    oggie
    wrote on last edited by
    #1

    Hola,

    Tengo una aplicación de escritorio que simula un CRUD y uso un buttondelegate
    para actualizar y borrar. La questión es que para cada delegate me despliega un
    botón de más.

    1.- clase ButtonColumnDelegate
    @
    ButtonColumnDelegate::ButtonColumnDelegate(QObject *parent) :
    QStyledItemDelegate(parent)
    {
    if(QTableView *tableView = qobject_cast<QTableView *>(parent))
    {
    myWidget = tableView;
    btn = new QPushButton("...", myWidget);
    btn->show();
    myWidget->setMouseTracking(true);
    connect(myWidget, SIGNAL(entered(QModelIndex)),
    this, SLOT(cellEntered(QModelIndex)));
    isOneCellInEditMode = false;
    }
    }

    ButtonColumnDelegate::~ButtonColumnDelegate()
    {

    }

    //createEditor
    QWidget * ButtonColumnDelegate::createEditor(QWidget *parent,
    const QStyleOptionViewItem &option,
    const QModelIndex &index) const
    {
    QString header = index.model()->headerData(index.column(), Qt::Horizontal, Qt::UserRole).toString();
    if ((header == "Update") || (header == "Insert"))
    {
    QPushButton * btn = new QPushButton(parent);
    btn->setText(index.data().toString());
    return btn;
    } else {
    return QStyledItemDelegate::createEditor(parent, option, index);
    }
    }

    //setEditorData
    void ButtonColumnDelegate::setEditorData(QWidget *editor,
    const QModelIndex &index) const
    {
    QString header = index.model()->headerData(index.column(), Qt::Horizontal, Qt::UserRole).toString();
    if ((header == "Update") || (header == "Insert"))
    {
    QPushButton * btn = qobject_cast<QPushButton *>(editor);
    btn->setProperty("data_value", index.data());
    } else {
    QStyledItemDelegate::setEditorData(editor, index);
    }
    }

    //setModelData
    void ButtonColumnDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
    const QModelIndex &index) const
    {
    QString header = index.model()->headerData(index.column(), Qt::Horizontal, Qt::UserRole).toString();
    if ((header == "Update") || (header == "Insert"))
    {
    QPushButton *btn = qobject_cast<QPushButton *>(editor);
    model->setData(index, btn->property("data_value"));
    } else {
    QStyledItemDelegate::setModelData(editor, model, index);
    }
    }

    //paint
    void ButtonColumnDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
    QString header = index.model()->headerData(index.column(), Qt::Horizontal, Qt::UserRole).toString();
    if((header == "Update") || (header == "Insert"))
    {
    btn->setGeometry(option.rect);
    btn->setText(index.data().toString());
    if (option.state == QStyle::State_Selected)
    painter->fillRect(option.rect, option.palette.highlight());
    QPixmap map = QPixmap::grabWidget(btn);
    painter->drawPixmap(option.rect.x(),option.rect.y(),map);
    } else {
    QStyledItemDelegate::paint(painter, option, index);
    }
    }

    //updateGeometry
    void ButtonColumnDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
    editor->setGeometry(option.rect);
    }

    //cellEntered
    void ButtonColumnDelegate::cellEntered(const QModelIndex &index)
    {
    QString header = index.model()->headerData(index.column(), Qt::Horizontal, Qt::UserRole).toString();
    if((header == "Update") || (header == "Insert"))
    {
    if(isOneCellInEditMode)
    {
    myWidget->closePersistentEditor(currentEditedCellIndex);
    }
    myWidget->openPersistentEditor(index);
    isOneCellInEditMode = true;
    currentEditedCellIndex = index;
    } else {
    if(isOneCellInEditMode)
    {
    isOneCellInEditMode = false;
    myWidget->closePersistentEditor(currentEditedCellIndex);
    }
    }
    }
    @

    Está tomado de internet "adding-button-to-qviewtable":http://qtadventures.wordpress.com/2012/02/04/adding-button-to-qviewtable/.

    2.- clase Browser (la ventana de la aplicación)
    @
    void Browser::exec()
    {
    QSqlQueryModel *myModel = new QSqlQueryModel(table);
    myModel->setQuery(QSqlQuery(sqlEdit->toPlainText(), connectionWidget->currentDatabase()));

    if (myModel->query().isSelect()) {
        // Create the data model
        model = new QStandardItemModel();
        table->setModel(model);
        ButtonColumnDelegate *update = new ButtonColumnDelegate(table);
        ButtonColumnDelegate *insert = new ButtonColumnDelegate(table);
        table->setItemDelegateForColumn(2, update);
        table->setItemDelegateForColumn(3, insert);
    
    
        model->insertRows(0, myModel->query().size());
        model->insertColumns(0, 4);
    
        // Set the localized header captions
        model->setHeaderData(0, Qt::Horizontal, "Id", Qt::UserRole);
        model->setHeaderData(1, Qt::Horizontal, "Word", Qt::UserRole);
        model->setHeaderData(2, Qt::Horizontal, "Update", Qt::UserRole);
        model->setHeaderData(3, Qt::Horizontal, "Insert", Qt::UserRole);
    
        // ...
    

    }
    @

    Y duplica el botón de la ultima fila.

    Gracias de antemano,
    oggie

    1 Reply Last reply
    0
    • O Offline
      O Offline
      oggie
      wrote on last edited by
      #2

      Creo que posiblemente la causa esté en la lógica de la función,
      @
      //cellEntered
      void ButtonColumnDelegate::cellEntered(const QModelIndex &index)
      {
      QString header = index.model()->headerData(index.column(), Qt::Horizontal, Qt::UserRole).toString();
      if((header == "Update") || (header == "Insert"))
      {
      if(isOneCellInEditMode)
      {
      myWidget->closePersistentEditor(currentEditedCellIndex);
      }
      myWidget->openPersistentEditor(index);
      isOneCellInEditMode = true;
      currentEditedCellIndex = index;
      } else {
      if(isOneCellInEditMode)
      {
      isOneCellInEditMode = false;
      myWidget->closePersistentEditor(currentEditedCellIndex);
      }
      }
      }
      @

      No estoy seguro dado que soy nuevo en esto pero posiblemente la variable booleana isOneCellInEditMode no esté bien controlada y habilite la opción de editar un botón de más.

      Cualquier sugerencia será gratamente apreciada.

      oggie

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

        Al final preferí usar esta otra clase con las correciones que aparecen en el código y ya funciona.

        customitemdelegate.h.-
        @
        #ifndef CUSTOMITEMDELEGATE_H
        #define CUSTOMITEMDELEGATE_H

        #include <QItemDelegate>

        class CustomItemDelegate : public QItemDelegate
        {
        Q_OBJECT

        public:
        explicit CustomItemDelegate(QObject *parent = 0);

        virtual void paint(QPainter *painter,
                           const QStyleOptionViewItem &option,
                           const QModelIndex &index) const ;
        
        virtual QSize sizeHint(const QStyleOptionViewItem &option,
                               const QModelIndex &index) const ;
        
        bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index);
        

        signals:
        void updButtonClicked(const QModelIndex &index);
        void delButtonClicked(const QModelIndex &index);

        public slots:

        private:
        QStyle::State _state;
        QRect oldRect;
        };

        #endif // CUSTOMITEMDELEGATE_H
        @

        customitemdelegate.cpp.-
        @
        #include "customitemdelegate.h"
        #include <QModelIndex>
        #include <QStandardItemModel>
        #include <QStandardItem>
        #include <QPainter>
        #include <QStyleOptionButton>
        #include <QApplication>
        #include <QEvent>
        #include <QDebug>
        #include <QMouseEvent>

        CustomItemDelegate::CustomItemDelegate(QObject *parent) :
        QItemDelegate(parent)
        {
        _state = QStyle::State_Enabled;
        }

        void CustomItemDelegate::paint(QPainter painter,
        const QStyleOptionViewItem &option,
        const QModelIndex &index) const
        {
        //const QStandardItemModel
        model = static_cast<const QStandardItemModel*>(index.model());
        //QStandardItem* item = model->item(index.row());
        //QString text = item->text();

        QString text = index.data().toString();

        QRect rect = option.rect;

        //QRect textRect(rect);
        //textRect.setHeight(30);
        //painter->drawText(textRect,text);
        painter->drawText(rect,text);

        QRect buttonRect(rect);
        //buttonRect.setY(textRect.y() + 35);
        //buttonRect.setY(rect.y() + 35);
        buttonRect.setHeight(30);
        QStyleOptionButton button;
        button.rect = buttonRect;
        button.text = text;
        button.state = _state | QStyle::State_Enabled;

        QApplication::style()->drawControl(QStyle::CE_PushButton, &button, painter);
        }

        QSize CustomItemDelegate::sizeHint(const QStyleOptionViewItem &/option/,
        const QModelIndex &/index/) const
        {
        return QSize(800,70);
        }

        bool CustomItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
        {
        qDebug() << "editorEvent on row: " << index.row();
        qDebug() << "editorEvent:: " << event->type();

        if( event->type() == QEvent::MouseButtonPress ||
            event->type() == QEvent::MouseButtonRelease ) {
        } else {
             _state = QStyle::State_Raised;
            return true;
        }
        
        QRect buttonRect(option.rect);
        //buttonRect.setY(option.rect.y() + 35);
        buttonRect.setHeight(30);
        
        QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
        if( !buttonRect.contains( mouseEvent->pos()) ) {
            _state = QStyle::State_Raised;
            return true;
        }
        
        if( event->type() == QEvent::MouseButtonPress) {
            _state = QStyle::State_Sunken;
        } else if(event->type() == QEvent::MouseButtonRelease) {
            _state = QStyle::State_Raised;
            if(index.data().toString().contains("Update"))
                emit updButtonClicked(index);
            else if(index.data().toString().contains("Delete"))
                emit delButtonClicked(index);
            else
                qDebug() << "¡¡¡ --ERROR-- !!!" << index.row();
        }
        return true;
        

        }
        @

        No duplicaba el ultimo botón sino que los había desplazado en la columna hacia abajo.

        Gracias,
        oggie

        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