QStyledItemDelegate与QComboBox和QTableView控件(如何传递信号)

时间:2017-10-20 00:40:14

标签: c++ qt qtableview qitemdelegate qstyleditemdelegate

我想知道是否有人可以用他/她的Qt编程的智慧和技巧让我朝着正确的方向前进,因为我的项目存在以下逻辑问题:

  1. 我使用QtableView

    使用三种不同的委托控件

    我。 ProdIdDelegate public QItemDelegate为m_prodid创建一个QcomboBox委托

    II。 QtySpinDelegate public QitemDelegate为m_qty创建一个QspinBox委托

    III。 TaxCDelegate public QitemDelegate为m_taxcode创建一个QcomboBox委托

  2. 所有这些委托都使用* m_modelo作为QstandardItem类集成在QtableView控件中。

  3. QtableView控件中共有7列

  4. 委托m_prodid填充数据库表字段产品代码,可以选择作为下拉项目列表。

  5. 所有三名代表分别有一个SIGNAL / SLOT他们适当的扫描搜索

  6. QcomboBox(m_prodid):CurrentIndexChanged(QString)SLOT(myscan descript_n_price)

    真正的问题是:

    从下拉组合框中选择任何项目后,其搜索结果(如描述和价格)可以显示在QtableView的列中,具有实时效果,即相同行选择的时间更改,描述,价格必须改变以及立即生效,并且必须同时更新显示。

    问题是CurrentIndexChange by Combo box发出的信号保留在它们的本地源文件中,它不会进入QtableView源文件的主控件,其中显示和计算所有格式化数据。

    以下源代码会让我们了解一下试图实现什么?   

    #ifndef PRODIDDELEGATE_H
    #define PRODIDDELEGATE_H
    #include "ak_connection.h"
    #include <QItemDelegate>
    #include <QStyledItemDelegate>
    #include <QComboBox>
    #include <vector>
    #include <string>
    
    class ProdIdDelegate : public QStyledItemDelegate
    {
        Q_OBJECT
    
    public:
        explicit ProdIdDelegate(QObject *parent = nullptr);
    
        QString getProdId () const { return m_proid;}
        QString getDescription () const { return m_description; }
        double getPrice () const { return m_price; }
        void setDescription (const QString &description) {m_description = description; }
        void setProdId(const QString &prodid) { m_proid = prodid; }
        void setPrice (const double &price) { m_price = price; }
    protected:
    
        QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                              const QModelIndex &index) const;
        void setEditorData(QWidget *editor, const QModelIndex &index) const;
        void setModelData(QWidget *editor, QAbstractItemModel *model,
                          const QModelIndex &index) const;
        void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
                                  const QModelIndex &index) const;
        void paint (QPainter *painter,
                    const QStyleOptionViewItem &option,
                    const QModelIndex &index) const;
        QSize sizeHint (const QStyleOptionViewItem &option,
                        const QModelIndex &index) const;
    private:
        void setValuesToVariable(QString str);
        std::vector<std::string> Items;
        QString m_proid;
        QString m_description;
        double m_price;
        AK_connection *akdb;
    
    private slots:
        void onComboItemChanged(const QString &text);
        void commitAndCloseEditor();
    };
    
    #endif // PRODIDDELEGATE_H
    

    实施文件

    #include "prodiddelegate.h"
    #include <QComboBox>
    #include <QDebug>
    #include <QStyledItemDelegate>
    #include <QSqlQuery>
    #include <QSqlError>
    
    // #define _TEST_
    
    ProdIdDelegate::ProdIdDelegate(QObject *parent)
        : QStyledItemDelegate (parent)
    {   
        (void) parent;
    #ifdef _TEST_
        m_description = "A Quick Borwn Fox Jump Over Little Lazy Dog.";
        m_price = 87634.90;
    
        Items.push_back("Test0");
        Items.push_back("Test1");
        Items.push_back("Test2");
        Items.push_back("Test3");
        Items.push_back("Test4");
        Items.push_back("Test5");
        Items.push_back("Test6");
        Items.push_back("Test7");
        Items.push_back("Test8");
        Items.push_back("Test9");
    #else
         akdb = new AK_connection(this);
         akdb->AK_open(true);
    #endif
    }
    
    QWidget *ProdIdDelegate::createEditor(QWidget *parent,
                                          const QStyleOptionViewItem &option,
                                          const QModelIndex &index) const
    {
        QComboBox *prodId = new QComboBox(parent);
    #ifndef _TEST_
        QSqlQuery q;
        q.prepare(QString("SELECT COALESCE(itemid,'') || " \
                          "COALESCE(description,'') AS ProdId " \
                          "FROM itemstbl WHERE status='1'"));
    
        if (!q.exec())
            qDebug () << q.lastError().text();
        while (q.next()) {
            prodId->addItem(q.value(0).toString());
        }
        q.clear();
    #else
        for (unsigned int i=0; i < Items.size(); i++)
            prodId->addItem(Items[i].c_str());
    #endif
        (void) option;
        (void) index;
    
        connect(prodId, SIGNAL(currentIndexChanged(QString)), this, SLOT(onComboItemChanged(QString)));
        return prodId;
    }
    void ProdIdDelegate::setEditorData(QWidget *editor,
                                       const QModelIndex &index) const
    {
        QStyledItemDelegate m_siDelegate;
    
        if (QComboBox *cb = qobject_cast <QComboBox *> (editor)) {
            QString curItem = index.data(Qt::EditRole).toString();
            int cbIndex = cb->findText(curItem);
            // Is it valid? then adjust.
            if (cbIndex >= 0)
                cb->setCurrentIndex(cbIndex);
        } else {
            m_siDelegate.setEditorData(editor, index);
        }    
    
    }
    void ProdIdDelegate::setModelData(QWidget *editor,
                                      QAbstractItemModel *model,
                                      const QModelIndex &index) const
    {
        QStyledItemDelegate m_siDelegate;
    
        if (QComboBox *cb = qobject_cast <QComboBox *> (editor)) {
            // Save current text of combo box to an item.
            model->setData(index, cb->currentText(), Qt::EditRole);
        } else {
            m_siDelegate.setModelData(editor, model, index);
        }
    }
    void ProdIdDelegate::updateEditorGeometry(QWidget *editor,
                                              const QStyleOptionViewItem &option,
                                              const QModelIndex &index) const
    {
        editor->setGeometry(option.rect);
        (void) index;
    }
    void ProdIdDelegate::paint(QPainter *painter,
                               const QStyleOptionViewItem &option,
                               const QModelIndex &index) const
    {
        (void) painter;
        (void) option;
        (void) index;
    }
    QSize ProdIdDelegate::sizeHint(const QStyleOptionViewItem &option,
                                   const QModelIndex &index) const
    {
       return QStyledItemDelegate::sizeHint(option, index);
    }
    
    void ProdIdDelegate::onComboItemChanged(const QString &text)
    {    
        emit commitData(qobject_cast <QWidget *> (sender()));
        setProdId(text.left(5));
        //qDebug () << "SIGNAL OnComboChanged gives string:" << text
                  //<< " File: " << __FILE__;
        setValuesToVariable(text.left(5));
    }
    
    void ProdIdDelegate::setValuesToVariable(QString str)
    {
    #ifdef _TEST_
        (void) str;
        setDescription(m_description);
        setPrice(m_price);
    #else
        QSqlQuery q; q.prepare(QString("SELECT description,price FROM itemstbl "
                                       "WHERE itemid ='%1'AND status='1'").arg(str));
        if (!q.exec())
            qDebug () << q.lastError().text();
    
        while (q.next()) {
            setDescription(q.value(0).toString());
            setPrice(q.value(1).toDouble());
        }
    #endif
        qDebug () << "Description:" << getDescription() << "Price:" << getPrice();
    }
    
    void ProdIdDelegate::commitAndCloseEditor()  // This signal yet to fired up.
    {
        QWidget *editor = qobject_cast <QWidget *> (sender());
        emit commitData(editor);
        emit closeEditor(editor);
    }
    

    主要dialog.cpp

    #include "dialog.h"
    #include "ui_dialog.h"
    #include "prodiddelegate.h"
    #include "vatdelegate.h"
    #include "qtyspin.h"
    #include <QStandardItemModel>
    #include <QTableWidget>
    #include <QDebug>
    #include <QLabel>
    #include <cassert>
    
    Dialog::Dialog(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::Dialog)
    {
        ui->setupUi(this);
        QDialog::setWindowTitle(">> Invoice Delegate <<");
        m_price = 20.87;
        m_vatrate = 0.0;
        m_qty     = 0;
        m_modelo         = new QStandardItemModel(this);
        m_prodIdDelegate = new ProdIdDelegate(this);
        m_qtyspinDelegate= new QtySpin(this);
        m_vatDelegate    = new VATDelegate(this);
    
        m_modelo->setRowCount(10);
        m_modelo->setColumnCount(7);
    
        m_modelo->setHorizontalHeaderItem(0, new QStandardItem("Prod ID"));
        m_modelo->setHorizontalHeaderItem(1, new QStandardItem("Description"));
        m_modelo->setHorizontalHeaderItem(2, new QStandardItem("Qty"));
        m_modelo->setHorizontalHeaderItem(3, new QStandardItem("Price"));
        m_modelo->setHorizontalHeaderItem(4, new QStandardItem("Amount"));
        m_modelo->setHorizontalHeaderItem(5, new QStandardItem("VATAmt"));
        m_modelo->setHorizontalHeaderItem(6, new QStandardItem("VAT"));
    
        ui->mytableView->setModel(m_modelo);
        assert (ui->mytableView->model());
    
        // set the column width
        ui->mytableView->setColumnWidth(0, 70);
        ui->mytableView->setItemDelegateForColumn(0, m_prodIdDelegate);
        ui->mytableView->showColumn(0);
        ui->mytableView->setColumnWidth(1, 400);
        ui->mytableView->setColumnWidth(2, 60);
        ui->mytableView->setItemDelegateForColumn(2, m_qtyspinDelegate);
        ui->mytableView->setColumnWidth(3, 80);
        ui->mytableView->setColumnWidth(4, 100);
        ui->mytableView->setColumnWidth(5, 80);
        ui->mytableView->setColumnWidth(6, 50);
        ui->mytableView->setItemDelegateForColumn(6, m_vatDelegate);
    
        QMetaObject::invokeMethod(ui->mytableView, "updateGeometries");
    
        for (int i=0; i<m_modelo->rowCount(); i++) {
            ui->mytableView->openPersistentEditor(m_modelo->index(i, 0));
            ui->mytableView->openPersistentEditor(m_modelo->index(i, 2));
            ui->mytableView->openPersistentEditor(m_modelo->index(i, 6));
        }
    
        ui->mytableView->show();
    }
    
    Dialog::~Dialog()
    {
        delete ui;
    }
    
    void Dialog::on_QuitpushButton_clicked()
    {
        close();
    }
    
    void Dialog::on_mytableView_clicked(const QModelIndex &index)
    {    (void) index;
        //qDebug() << "SIGNAL: QTableView_clicked at Row " <<  index.row() << " Column " << index.column();
        //qDebug () << "SIGNAL FROM Dialog_clicked " << ui->mytableView->model()->data(index).toString();
        //int curCol = index.column();
    /*
        switch (curCol) {
            case 0:
                qDebug () << "ProdID " << ui->mytableView->model()->data(index).toString();
                GetCurrentItem(index.row());
              break;
            case 2:
                m_qty = ui->mytableView->model()->data(index).toInt();
                qDebug () << "Qty" << m_qty;
                putAmount(index.row());
              break;
            case 6:
                QString code = ui->mytableView->model()->data(index).toString();
                qDebug () << "VAT code " << code;
                switch (code.data()->toLatin1())
                {
                    case 'S': m_vatrate = 20.0; break;
                    case 'H': m_vatrate = 10.0; break;
                    case 'Q': m_vatrate =  5.0; break;
                    case 'E':
                    case 'Z': m_vatrate = 0.0; break;
                    default:  m_vatrate = 0.0;
                }
                putVatAmt (index.row());
              break;
            //default:
           }  */
        qDebug () << "Description" << m_prodIdDelegate->getProdId();
        qDebug () << "Price" << m_prodIdDelegate->getPrice();
        qDebug () << "QTY came:" << m_qtyspinDelegate->getQty();
        qDebug () << "VAT Rate came" << m_vatDelegate->getVATRate();
    }
    
    void Dialog::on_mytableView_doubleClicked(const QModelIndex &index)
    {
        qDebug() << "SIGNAL: QTableView_doubleClicked at Row " << index.row() << " Column " << index.column();
    }
    
    void Dialog::GetCurrentItem(int rowCount)
    {   QString myprc = QString("%1").arg(m_price);
        QStandardItem *m_descrpt = new QStandardItem("This is a test procedure");
        QStandardItem *m_pric   = new QStandardItem(myprc);
        m_modelo->setItem(rowCount, 1, m_descrpt);
        m_modelo->setItem(rowCount, 3, m_pric);
    }
    
    void Dialog::putAmount(int rowCount)
    {
        double amt = m_price * m_qty;
        QString stramt = QString("%1").arg(amt);
        QStandardItem *m_amt     = new QStandardItem(stramt);
        m_modelo->setItem(rowCount, 4, m_amt);
    }
    void Dialog::putVatAmt(int rowCount)
    {
        qDebug () << "VATrate" << m_vatrate;
        double vatam = (((m_price * m_qty) * m_vatrate) /100);
        QString strvat = QString("%1").arg(vatam);
        QStandardItem  *m_vatamt = new QStandardItem(strvat);
        m_modelo->setItem(rowCount, 5, m_vatamt);
    }
    

    标题文件dialog.h

    #ifndef DIALOG_H
    #define DIALOG_H
    
    #include <QDialog>
    
    namespace Ui {
    class Dialog;
    }
    
    class QStandardItemModel;
    class ProdIdDelegate;
    class VATDelegate;
    class QtySpin;
    class QTableWidget;
    
    class Dialog : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit Dialog(QWidget *parent = nullptr);
        ~Dialog();
    
    private slots:
        void on_QuitpushButton_clicked();
        void on_mytableView_clicked(const QModelIndex &index);
        void on_mytableView_doubleClicked(const QModelIndex &index);
        void GetCurrentItem(int rowCount);
        void putAmount(int rowCount);
        void putVatAmt(int rowCount);
    private:
        Ui::Dialog *ui;
    
        QStandardItemModel *m_modelo;
        ProdIdDelegate     *m_prodIdDelegate;
        QtySpin            *m_qtyspinDelegate;
        VATDelegate        *m_vatDelegate;
        QTableWidget       *m_curRow;
        QString            m_pid;
        double             m_vatrate;
        double             m_price;
        int                m_qty;
    };
    
    #endif // DIALOG_H
    

    以下png图像给出了源代码应该做的假设吗?

    来自上述源代码的预期逻辑

    结果:

    enter image description here

0 个答案:

没有答案