1

我想知道是否有人可以凭借他/她的 Qt 编程智慧和技能将我引向正确的方向,因为我的项目存在以下逻辑问题:

  1. 我在 QtableView 中使用了三种不同的委托控件

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

    ii. QtySpinDelegate public QitemDelegate 为 m_qty 创建一个 QspinBox 委托

    iii. TaxCDelegate public QitemDelegate 为 m_taxcode 创建一个 QcomboBox 委托

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

  3. QtableView控件共有7列

  4. 委托 m_prodid 填充数据库表字段产品代码并准备好作为下拉项目列表进行选择。

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

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

真正的问题是:

从下拉组合框中选择任何项目后,其搜索结果(例如描述和价格)可以实时显示在 QtableView 的列中,即同一行选择更改的次数,描述,价格必须随着即时效果和显示必须同时更新。

问题是组合框发出的 CurrentIndexChange 发出的信号保留在其本地源文件中,它没有进入 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);
}

主对话框.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 图像给出了源代码应该做什么的假设?

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

结果:

在此处输入图像描述

4

0 回答 0