PDA

View Full Version : Weird application crash



MarkoSan
17th May 2008, 01:16
Hi to all!

I need help because I stumbled into pitfall I cannot solve. In my app module I have QTableView subclassed object which represents data from subclassed QStandardItemModel object. This QStandardItemModel subclassed object internally holds QList of some data. Now, when I empty this QList with clear() method and after I clear QTableView also using its inherited clear method with following code chunk:
m_pShoppingCartView->order()->orders()->clear(); // reinits order list
m_pShoppingCartView->shoppingCartModel()->clear(); // clears table view my app crashes with gdb error:
warning: ASSERT: "i >= 0 && i < size()" in file ../../include/QtCore/../../src/corelib/tools/qbitarray.h, line 121. The application crashes when I readd items to qlist and then render data of this qlist using model on table view. Why the app crashes?!

MarkoSan
17th May 2008, 07:21
Sometimes I also get:
warning: ASSERT: "i >= 0 && i < size()" in file ../../include/QtCore/../../src/corelib/tools/qbitarray.h, line 121

warning: QPaintEngine::setSystemClip: Should not be changed while engine is active

warning: QPaintEngine::setSystemClip: Should not be changed while engine is active

warning: QWidgetPrivate::beginSharedPainter: Painter is already active

warning: QPainter::begin: A paint device can only be painted by one painter at a time.

warning: QPainter::begin: A paint device can only be painted by one painter at a time.

warning: ASSERT: "sharedPainter ? sharedPainter->isActive() : true" in file kernel\qwidget.cpp, line 4420

wysota
17th May 2008, 10:10
How is the order list related to the model? Do you emit proper signals when changing the model?

MarkoSan
18th May 2008, 20:07
Well, here is model header:
#ifndef CSHOPPINGCARTMODEL_H_
#define CSHOPPINGCARTMODEL_H_

// qt includes
//#include <QAbstractTableModel>
#include <QStandardItemModel>
#include <QModelIndex>
#include <QString>

#include "CMerchandizeOrder.h"

//class CShoppingCartModel : public QAbstractTableModel
class CShoppingCartModel : public QStandardItemModel
{
public:
CShoppingCartModel(CMerchandizeOrder* pMerchandizeOrder,
QObject* pParent=0);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount (const QModelIndex & parent=QModelIndex()) const;
QVariant data(const QModelIndex &index, int role) const;
/*
bool setData(const QModelIndex &index,
const QVariant &value,
int role);
*/

inline CMerchandizeOrder* order()
{ return m_pMerchandizeOrder; };
private:
CMerchandizeOrder* m_pMerchandizeOrder;
};

#endif /*CSHOPPINGCARTMODEL_H_*/

and its implementation:
#include "CShoppingCartModel.h"

CShoppingCartModel::CShoppingCartModel(CMerchandiz eOrder* pMerchandizeOrder,
QObject* pParent)
// : QAbstractTableModel(pParent), m_pMerchandizeOrder(pMerchandizeOrder)
: QStandardItemModel(pParent), m_pMerchandizeOrder(pMerchandizeOrder)
{
setColumnCount(1); // sets column count
setRowCount(pMerchandizeOrder->orders()->size()); // sets row count
}

int CShoppingCartModel::rowCount(const QModelIndex& parent) const
{
return m_pMerchandizeOrder->orders()->size();
}

int CShoppingCartModel::columnCount (const QModelIndex& parent) const
{
return 1;
}

QVariant CShoppingCartModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if(index.isValid() && role==Qt::DisplayRole)
return m_pMerchandizeOrder->orders()->at(index.row()).strDisplayString;
//QStandardItemModel::data(index, role);
if(index.isValid() && role==Qt::FontRole)
return QFont("Courier New",
18,
QFont::Normal/*QFont::Bold*/);
return QVariant(); // returns invalid record
}

/*
bool CShoppingCartModel::setData(const QModelIndex &index,
const QVariant &value,
int role)
{
emit dataChanged(index, index);
return true;
}
*/

totycro
19th May 2008, 11:10
You could try to use a debugger (e.g. gdb on linux) to pinpoint the exact location where the application crashes. This usually also reveals error that causes the crash.

MarkoSan
19th May 2008, 12:17
You could try to use a debugger (e.g. gdb on linux) to pinpoint the exact location where the application crashes. This usually also reveals error that causes the crash.


Wll I did that, how could I otherwise show error strings ?!

wysota
19th May 2008, 12:46
What is the point of having a QStandardItemModel if you reimplement all of its functionality to operate on a list? Either use QStringListModel with a simple reimplementation to return another font (although you can do that on the view level) or use QStandardItemModel properly. The extra list is completely redundant here.

MarkoSan
20th May 2008, 10:04
wysota, will fix that, now it is mandatory to make the code work. Here is the code that uses model:
// slot for choosing merchandize
void COperationWIndow::chooseMerchandize()
{
structOrder tmpOrder; // temp order
QList<QStandardItem*> OrderItemList; // order model item list

qDebug() << "m_iSelected: " << m_pMerchandizeBrowser->m_iSelected;
// FIXED: m_pMerchandizeBrowser->m_iSelected does not correctly show the index of selected image
/*
tmpOrder.iMerchandizeID=1;
tmpOrder.iMerchandizeQuantity=25;
tmpOrder.rMerchandizePrice=4.00;
tmpOrder.rSubtotal=tmpOrder.iMerchandizeQuantity*t mpOrder.rMerchandizePrice;
tmpOrder.strMerchandizeName=QString("Testni Artikel");
tmpOrder.strDisplayString=QString::number(tmpOrder .iMerchandizeID)+strMerchandizeSpaceDelimiter+\
QString(tmpOrder.strMerchandizeName)+strMerchandiz eDelimiter+\
QString::number(tmpOrder.rMerchandizePrice, 'f', iMerchandizePricePrecision)+strMerchandizeSpaceDel imiter+\
QString::number(tmpOrder.iMerchandizeQuantity)+str MerchandizeSpaceDelimiter+\
QString::number(tmpOrder.rSubtotal, 'f', iMerchandizePricePrecision);
qDebug() << "tmpOrder.strDisplayString=" << tmpOrder.strDisplayString;
*/

// TODO: language id number must not be ignored in sql statement
QString queryString("SELECT * from merchandize WHERE IdentificationNumber=%1 AND InUse=1;");
int iMerchandizeId=m_pMerchandizeBrowser->m_iSelected+1; // calcualtes id
queryString=queryString.arg(iMerchandizeId); // adds id to query string
qDebug() << "Query: " << queryString; // debug
QSqlQuery query(queryString); // sets up query from query string
qDebug() << query.lastError().text(); // debug
if (query.isActive())
{
while (query.next())
{
tmpOrder.iMerchandizeID=query.value(0).toInt();
tmpOrder.iMerchandizeQuantity=1;
tmpOrder.rMerchandizePrice=(qreal)query.value(3).t oDouble();
tmpOrder.rSubtotal=tmpOrder.iMerchandizeQuantity*t mpOrder.rMerchandizePrice;
tmpOrder.strMerchandizeName=QString(query.value(2) .toString());
tmpOrder.strDisplayString=QString::number(tmpOrder .iMerchandizeID)+strMerchandizeSpaceDelimiter+\
QString(tmpOrder.strMerchandizeName)+strMerchandiz eDelimiter+\
QString::number(tmpOrder.rMerchandizePrice, 'f', iMerchandizePricePrecision)+strMerchandizeSpaceDel imiter+\
QString::number(tmpOrder.iMerchandizeQuantity)+str MerchandizeSpaceDelimiter+\
QString::number(tmpOrder.rSubtotal, 'f', iMerchandizePricePrecision);
}


if(m_pShoppingCartView->order()->orders()->size()<=0)
{
// size of orders is zero, adds record to table
m_pShoppingCartView->order()->orders()->append(tmpOrder); // adds order to internal qlist
QStandardItem* pItem=new QStandardItem(QString(tmpOrder.strDisplayString));
Q_CHECK_PTR(pItem); // checks creation
m_pShoppingCartView->shoppingCartModel()->appendRow(pItem);
}
else
{
for(qint16 iIndex=0; iIndex<(qint16)m_pShoppingCartView->order()->orders()->size(); iIndex++)
{
qDebug() << " m_pShoppingCartView->order()->orders()->at((int)iIndex).iMerchandizeID (" \
<< m_pShoppingCartView->order()->orders()->at((int)iIndex).iMerchandizeID << ")==" \
<< "tmpOrder.iMerchandizeID (" << tmpOrder.iMerchandizeID << ")?";
if(m_pShoppingCartView->order()->orders()->at((int)iIndex).iMerchandizeID==tmpOrder.iMerchand izeID)
/*
qDebug() << " iMerchandizeId (" << iMerchandizeId \
<< "tmpOrder.iMerchandizeID (" << tmpOrder.iMerchandizeID << ")?";
if(iMerchandizeId==tmpOrder.iMerchandizeID)
*/
{
// orderer merchandize found, so
tmpOrder.iMerchandizeQuantity++; // update quantity
tmpOrder.rSubtotal=tmpOrder.iMerchandizeQuantity*t mpOrder.rMerchandizePrice; // update total
tmpOrder.strDisplayString=QString::number(tmpOrder .iMerchandizeID)+strMerchandizeSpaceDelimiter+\
QString(tmpOrder.strMerchandizeName)+strMerchandiz eDelimiter+\
QString::number(tmpOrder.rMerchandizePrice, 'f', iMerchandizePricePrecision)+strMerchandizeSpaceDel imiter+\
QString::number(tmpOrder.iMerchandizeQuantity)+str MerchandizeSpaceDelimiter+\
QString::number(tmpOrder.rSubtotal, 'f', iMerchandizePricePrecision);
m_pShoppingCartView->order()->orders()->replace((int)iIndex, tmpOrder); // saves changes
m_pShoppingCartView->shoppingCartModel()->clear(); // clears table view
for(qint16 iIndex=0; iIndex<(qint16)m_pShoppingCartView->order()->orders()->size(); iIndex++)
{
QStandardItem* pItem=new QStandardItem(QString(tmpOrder.strDisplayString)); // creates new item from order
Q_CHECK_PTR(pItem); // checks creation
OrderItemList.append(pItem); // adds item to list
//m_pShoppingCartView->shoppingCartModel()->appendRow(pItem); // adds items
}
m_pShoppingCartView->shoppingCartModel()->appendRow(OrderItemList); // adds items
break;
}
else
{
// ordered merchandize not found, so adds it
m_pShoppingCartView->order()->orders()->append(tmpOrder); // adds order to internal qlist
QStandardItem* pItem=new QStandardItem(QString(tmpOrder.strDisplayString)); // creates new item from list
Q_CHECK_PTR(pItem); // checks creation
m_pShoppingCartView->shoppingCartModel()->appendRow(pItem);
break;
} // for
} // for
} // if
/*
m_pShoppingCartView->resizeColumnsToContents();
m_pShoppingCartView->resizeRowsToContents();
*/
if(m_pOrderButton->isEnabled()==false)
m_pOrderButton->setEnabled(true); // enables order buttn
} // if
}The code
/*
m_pShoppingCartView->resizeColumnsToContents();
m_pShoppingCartView->resizeRowsToContents();
*/ is commented because here the app crashes by resizeRows. Why?!

wysota
20th May 2008, 10:10
You can't make an incorrect code work. Finding the real problem with a bad design will take more time than rewriting it using correct solutions. Either implement the model by subclassing from QAbstractListModel or switch to QStandardItemModel completely.

MarkoSan
20th May 2008, 10:15
I've switched to QStandardItemModel, you saw it in the header file!!

And the order list simply cannot be redundant because I need it in other parts of project. So I cannot have QStandardModel with this list or what now?!

wysota
20th May 2008, 14:13
I've switched to QStandardItemModel, you saw it in the header file!!
No, you didn't. You subclassed the model (and did it incorrectly) and not used it.


And the order list simply cannot be redundant because I need it in other parts of project. So I cannot have QStandardModel with this list or what now?!
I don't know what can or can't be. I know all the functionality of your list is already in the standard item model. So either don't use the list or don't use QStandardItemModel. A proper approach is to get rid of QStandardItemModel, but it's more work to implement your own model instead of using the standard one.