у меня большие проблемы с обновлением пользовательской модели qabstracttable. я хочу иметь табличное представление, которое показывает цены нескольких акций. я получаю цены с локального сервера, который я контролирую. эта установка предназначена для тестирования. информация о ценах получена в рабочем потоке.
я создал подкласс qabstracttablemodel следующим образом:
ЦенаМодель.ч:
class PriceModel : public QAbstractTableModel {
Q_OBJECT
public:
PriceModel( QObject* parent = 0 );
void setPriceMap( const QMap<QString, ITick*> &curTickMap );
int rowCount( const QModelIndex &parent ) const;
int columnCount( const QModelIndex &parent ) const;
QVariant data( const QModelIndex &index, int role ) const;
QVariant headerData( int section, Qt::Orientation orientation, int role ) const;
private:
QMap<QString, ITick*> currentTicks;
QString stockAt( int offset ) const;
};
PriceModel.cpp
#include "PriceModel.h"
PriceModel::PriceModel( QObject* parent ) : QAbstractTableModel( parent ) {
}
int PriceModel::rowCount( const QModelIndex& parent ) const {
return this->currentTicks.count();
}
int PriceModel::columnCount( const QModelIndex& parent ) const {
return 4;
}
QString PriceModel::stockAt( int offset ) const {
return ( currentTicks.begin() + offset ).key();
}
QVariant PriceModel::data( const QModelIndex& index, int role ) const {
if ( !index.isValid() ) {
return QVariant();
}
if ( role == Qt::TextAlignmentRole ) {
return int( Qt::AlignRight | Qt::AlignVCenter );
} else if ( role == Qt::DisplayRole ) {
QString stock = stockAt( index.row() );
int i = index.column();
switch ( i ) {
case 0 : return currentTicks.value( instrument )->getTime().toString( "hh:mm:ss:zzz" );
case 1 : return currentTicks.value( instrument )->getBid();
case 2 : return currentTicks.value( instrument )->getAsk();
case 3 : return currentTicks.value( instrument )->getBidVolume();
case 4 : return currentTicks.value( instrument )->getAskVolume();
}
}
return QVariant();
}
QVariant PriceModel::headerData( int section, Qt::Orientation orientation, int role ) const {
if ( role != Qt::DisplayRole ) {
return QVariant();
}
if ( orientation == Qt::Horizontal ) {
switch ( section ) {
case 0 : return QString( "Time" );
case 1 : return QString( "Bid" );
case 2 : return QString( "Ask" );
case 3 : return QString( "Bid Volume" );
case 4 : return QString( "Ask Volume" );
}
} else {
return instrumentAt( section )->getCurrencyPairWithDelimiter();
}
return QVariant();
}
void PriceModel::setTickMap( const QMap<QString,ITick*>& curTickMap ) {
beginResetModel();
this->currentTicks = curTickMap;
endResetModel();
}
модель заполняет табличное представление, когда я вызываю метод setTickMap(qmap‹...>), и все различные акции отображаются так, как ожидалось. (инициализация данных в моей модели работает нормально)
проблема возникает, когда я хочу снова вызвать метод setTickMap(qmap‹...>). приложение аварийно завершает работу, и я не понимаю, почему, и я не получаю серьезного сообщения об ошибке, а именно segvault.
при сбое в конфигурации отладки netbeans открывает вкладку «Разборка» со следующим содержимым:
QMetaObject::activate(QObject*, QMetaObject const*, int, void**)+50: add %ebx,%r15d
QMetaObject::activate(QObject*, QMetaObject const*, int, void**)+85: testb $0x4,0x20(%rax)
QMetaObject::activate(QObject*, QMetaObject const*, int, void**)+89: jne 0x7ffff63f4df8 <QMetaObject::activate(QObject*, QMetaObject const*, int, void**)+536>
QMetaObject::activate(QObject*, QMetaObject const*, int, void**)+102: add 0x6c(%rsp),%ebx
QMetaObject::activate(QObject*, QMetaObject const*, int, void**)+118: mov %ebx,0x2c(%rsp)
QMetaObject::activate(QObject*, QMetaObject const*, int, void**)+106: movq $0x0,0x40(%rsp)
QMetaObject::activate(QObject*, QMetaObject const*, int, void**)+95: mov 0x31c19a(%rip),%rdx # 0x7ffff6710de0
QMetaObject::activate(QObject*, QMetaObject const*, int, void**)+115: mov (%rdx),%rax
QMetaObject::activate(QObject*, QMetaObject const*, int, void**)+122: test %rax,%rax
QMetaObject::activate(QObject*, QMetaObject const*, int, void**)+125: je 0x7ffff63f4c72 <QMetaObject::activate(QObject*, QMetaObject const*, int, void**)+146>
QMetaObject::activate(QObject*, QMetaObject const*, int, void**)+127: lea 0x40(%rsp),%rdx
QMetaObject::activate(QObject*, QMetaObject const*, int, void**)+132: test %r13,%r13
QMetaObject::activate(QObject*, QMetaObject const*, int, void**)+135: mov %ebx,%esi
QMetaObject::activate(QObject*, QMetaObject const*, int, void**)+137: mov %r12,%rdi
QMetaObject::activate(QObject*, QMetaObject const*, int, void**)+140: cmovne %r13,%rdx
QMetaObject::activate(QObject*, QMetaObject const*, int, void**)+144: callq *%rax
я засунул назначение карты в методы beginResetModel(), но это, похоже, не работает, так как я просто получаю сбой приложения. как ни странно это работает при первом вызове метода установки. это заставляет меня предположить, что это довольно глупая ошибка. я думаю, поскольку первый вызов работает нормально, мы можем исключить, что это как-то связано с проблемами межпотоковой связи.
эта модель не должна редактироваться пользователем через графический интерфейс, и я знаю, что мог бы использовать табличный виджет только для отображения данных, но я не уверен, будет ли другое представление, которое будет делиться информацией об этой модели. карта с текущими ценами не будет очень большой (максимум 25 предметов), поэтому мне не неудобно сбрасывать модель при каждой новой поступающей цене.
заранее спасибо, и я надеюсь, что кто-то может помочь мне с этим micropor
currentTicks
- этоQMap<QString, ITick*>
, а вашsetTickMap
имеет в качестве аргументаQMap<IInstrument*,ITick*>
. - person pnezis   schedule 16.01.2012