我想知道是否有人可以凭借他/她的 Qt 编程智慧和技能将我引向正确的方向,因为我的项目存在以下逻辑问题:
我在 QtableView 中使用了三种不同的委托控件
一世。ProdIdDelegate public QItemDelegate 为 m_prodid 创建一个 QcomboBox 委托
ii. QtySpinDelegate public QitemDelegate 为 m_qty 创建一个 QspinBox 委托
iii. TaxCDelegate public QitemDelegate 为 m_taxcode 创建一个 QcomboBox 委托
所有这些委托都集成在 QtableView 控件中,使用 *m_modelo 作为 QstandardItem 类。
QtableView控件共有7列
委托 m_prodid 填充数据库表字段产品代码并准备好作为下拉项目列表进行选择。
所有三个代表都有一个 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 图像给出了源代码应该做什么的假设?
来自上述源代码的预期逻辑
结果: