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
Forum Update on Monday, May 27th 2025

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 11 Aug 2012, 14:20 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 13 Aug 2012, 04:56 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 18 Aug 2012, 06:51 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

        3/3

        18 Aug 2012, 06:51

        • Login

        • Login or register to search.
        3 out of 3
        • First post
          3/3
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved