我偶然发现了一个让我有点困惑的问题。
在这个小部件的构造函数中,我调用了一个填充表的函数fillQualityReport()
:
RepackProcess::RepackProcess(DataBase *d, QPrinter *p, QWidget *parent) : QMdiSubWindow(parent), ui(new Ui::RepackProcess)
{
ui->setupUi(this);
data=d;
printer=p;
loadDropDownMenus();
fillQualityReport();
connect(ui->quality,SIGNAL(cellChanged(int,int)),this,SLOT(updateTotalLosses()));
}
以下是填写质量报告的功能:
void RepackProcess::fillQualityReport()
{
int commodity;
QSqlQuery query, defects;
query.prepare("select * from commodity where (name=:name)"); // Looking for the commodity id
query.bindValue(":name",ui->Commodity->currentText());
query.exec();
query.next();
commodity=query.value(0).toInt();
query.prepare("select * from quality where (id_commodity=:commodity)");
query.bindValue(":commodity",commodity);
query.exec();
query.next();
query.last();
totalQualityDefects = query.at()<0 ? 0 : query.at()+1;
ui->quality->setColumnCount(2); // Setting the column and row counts for the table
ui->quality->setRowCount(totalQualityDefects);
ui->quality->setHorizontalHeaderLabels(QString("Defect;Percent").split(";"));
ui->quality->setColumnWidth(0,60);
ui->quality->setColumnWidth(1,60);
query.first(); // Movind the pointer of the query back to before the first record
query.previous();
int currentRow=0;
while (query.next()) { // Filling the table with the defect names
defects.prepare("select name from defects where (id=:id)");
defects.bindValue(":id",query.value(2).toInt());
defects.exec();
defects.next();
ui->quality->setItem(currentRow,0,new QTableWidgetItem(defects.value(0).toString()));
ui->quality->setItem(currentRow,1,new QTableWidgetItem(QString::number(0.00,'f',2)));
ui->quality->item(currentRow,1)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
currentRow++;
}
}
这里是质量报告发生变化时更新表格的那个:
void RepackProcess::updateTotalLosses()
{
totalLoss=0;
QSqlQuery query;
query.prepare("select * from commodity where name=:name");
query.bindValue(":name",commodityLabel);
query.exec();
query.next();
int commodityId=query.value(0).toInt();
for(int x=0; x<totalQualityDefects;x++)
{
qDebug()<<x;
QString defect=ui->quality->item(x,0)->text();
qDebug()<<defect;
query.prepare("select * from defects where name=:name");
query.bindValue(":name",defect);
query.exec();
query.next();
int defectId = query.value(0).toInt();
query.prepare("select * from quality where (id_commodity=:commodity and id_defects=:defects)");
query.bindValue(":commodity",commodityId);
query.bindValue(":defects",defectId);
query.exec();
query.next();
qDebug()<<query.lastError();
if(ui->quality->item(x,1)->text().toFloat()<query.value(3).toFloat())
{
totalLoss += ui->quality->item(x,1)->text().toFloat() * query.value(4).toFloat();
}
else if(ui->quality->item(x,1)->text().toFloat()<query.value(5).toFloat())
{
totalLoss += ui->quality->item(x,1)->text().toFloat() * query.value(6).toFloat();
}
else
{
totalLoss += ui->quality->item(x,1)->text().toFloat() * query.value(8).toFloat();
}
}
ui->totalLoss->setText(QString::number(totalLoss,'f',2));
}
我的问题如下,使用构造函数上的connect函数,填写表时出错。在我看来,程序在表完全填充之前调用更新函数,程序在表的第二行崩溃。当表格被填满时,连接会通知数据发生变化并触发更新,该更新知道表格中的行数
如果我取出连接并更换一个按钮进行更新工作没有问题。我正在查看表格视图中的所有信号,但找不到仅在屏幕上访问数据时触发的信号。
很抱歉这篇长篇文章,但你总是要求代码。
#ifndef REPACKPROCESS_H
#define REPACKPROCESS_H
#include <QWidget>
#include <QMdiSubWindow>
#include <QPrinter>
#include "database.h"
namespace Ui {
class RepackProcess;
}
class RepackProcess : public QMdiSubWindow
{
Q_OBJECT
public:
explicit RepackProcess(DataBase *d, QPrinter *p, QWidget *parent = 0);
~RepackProcess();
void fillQualityReport(void); // This function will resize and change the quality table for imput
void loadDropDownMenus(void); // This function reads the tables and adds the selection to the drop down.
void updateRepackCost(void); // This function updates the costs table when parameters are changed
void updateSheetCalculation(void); // This function updates all the calculations of the sheet
private slots:
void on_Commodity_activated(const QString &arg1);
void on_Warehouse_activated(const QString &arg1);
void on_Format_activated(const QString &arg1);
void on_totalCases_valueChanged(int arg1);
void updateTotalLosses(int col, int row); // This function updates the estimated total loses
void on_updateLoss_clicked();
private:
Ui::RepackProcess *ui;
DataBase *data;
QPrinter *printer;
QSqlRelationalTableModel *costsModel;
QString countryLabel, commodityLabel, modeLabel, warehouseLabel, formatLabel;
int totalCases; // This is the total number of cases that started the process
float totalLoss; // Thi is the percentage of total loses in the process.
int totalQualityDefects; // This is the number of defect that are showing on the quality report.
};
#endif // REPACKPROCESS_H
答案 0 :(得分:0)
这句话你可能是对的:
在我看来,该程序之前正在调用更新函数 表完全
由于您更改了一个单元格:
connect(ui->quality,SIGNAL(cellChanged(int,int)),this,SLOT(updateTotalLosses()));
使用,因此调用updateTotalLosses()
。
要解决此问题,请使用以下方法阻止自身发出信号:
ui->quality->blockSignals(true);
ui->quality->blockSignals(false);
所以你需要做这样的事情:
fillQualityReport()
{
ui->quality->blockSignals(true);
... // your code
ui->quality->blockSignals(false);
}
和
updateTotalLosses()
{
ui->quality->blockSignals(true);
... // your code
ui->quality->blockSignals(false);
}