Qt-interest Archive, May 2007
TableView Row & Col switch
Message 1 in thread
I am having trouble getting a QTableView to work correctly. Below find
the code. When I run the program, the Table appears, but the rows &
columns are switched, e.g. Qt puts the header items that should be
column headings into rows, and the data() method is never entered, even
thought the rowCount method always returns the size of the items list >
0. This is Qt 4.2.3
I am sure it is something silly, can somone put their finger on it?
My class declaration looks like this:
class TModBxBBrthList : public QAbstractTableModel
{
Q_OBJECT
public :
TModBxBBrthList(QObject *parent=0):QAbstractTableModel(parent)
{
m_DataDeque.clear();
};
etc....
I overload the following QAbstractTableModel methods:
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;
Qt::ItemFlags flags ( const QModelIndex & index ) const;
here are the definitions:
int
TModBxBBrthList::rowCount(const QModelIndex &) const
{
int iRet=size();
return iRet;
}
int
TModBxBBrthList::columnCount(const QModelIndex &parent) const
{
int iRet=m_VarList.size();
iRet=(iRet>0)?iRet-1:0;
return iRet;
}
QVariant
TModBxBBrthList::data(const QModelIndex &index, int role) const
{
if ((index.isValid()) && (index.row() < size()))
{
if (role == Qt::TextAlignmentRole)
{
return int(Qt::AlignRight | Qt::AlignVCenter);
}
else
{
if (role == Qt::DisplayRole)
{
const TModBxBBrthItem0 *item=getBrthItem(index.row());
if (!item)
return QVariant();
if (index.column()<m_VarList.size())
{
double amount = item->getData(m_VarList[index.column()]);
return QString("%1").arg(amount, 0, 'f', 3);
}
else
return QVariant();
}
}
}
}
extern const char _modReqrdDataNames[];
extern const char _modDesrdDataNames[];
QVariant
TModBxBBrthList::headerData(int section, Qt::Orientation orientation,
int role) const
{
// NOTE: if we accept Qt::Vertical, the program displays what should
// be column headings in the left column as row headings!!!
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
{
QStringList rdn=QString(_modReqrdDataNames ).split(',');
QStringList ddn=QString(_modDesrdDataNames).split(',');
size_t rsz=rdn.size();
size_t dsz=ddn.size();
if (section<rsz)
return rdn[section];
else
if (section<rsz+dsz)
return ddn[section-rsz];
else
return QVariant();
}
else
return QVariant();
}
Qt::ItemFlags
TModBxBBrthList::flags ( const QModelIndex & index ) const
{
// return QAbstractItemModel::flags(index);
if ((index.row()<size()) && (index.column()<columnCount(QModelIndex())))
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
else
return 0;
}
--
[ signature omitted ]
Message 2 in thread
Kenneth Beck schrieb:
> and the data() method is never entered, even
> thought the rowCount method always returns the size of the items list >
> 0.
This part of your problem may be due to no column being defined, thus no
cells are there to be filled with data.
> int
> TModBxBBrthList::columnCount(const QModelIndex &parent) const
> {
> int iRet=m_VarList.size();
> iRet=(iRet>0)?iRet-1:0;
Just make sure this returns the actual number of columns; this looks as
if you've built in a reverse off-by-one error here...?
> QVariant
> TModBxBBrthList::headerData(int section, Qt::Orientation orientation,
> int role) const
> {
> // NOTE: if we accept Qt::Vertical, the program displays what should
> // be column headings in the left column as row headings!!!
> if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
> {
Seems OK to me - it returns the column headers to display. If
orientation == Qt::Vertical the view is asking for the row "headers".
Are you sure you didn't confuse horizontal and vertical for a moment?
HTH, Martin
--
[ signature omitted ]
Message 3 in thread
Martin Gebert wrote:
> Kenneth Beck schrieb:
>> and the data() method is never entered, even thought the rowCount
>> method always returns the size of the items list > 0.
>
> This part of your problem may be due to no column being defined, thus no
> cells are there to be filled with data.
>
>> int
>> TModBxBBrthList::columnCount(const QModelIndex &parent) const
>> {
>> int iRet=m_VarList.size();
>> iRet=(iRet>0)?iRet-1:0;
>
> Just make sure this returns the actual number of columns; this looks as
> if you've built in a reverse off-by-one error here...?
>
>> QVariant
>> TModBxBBrthList::headerData(int section, Qt::Orientation orientation,
>> int role) const
>> {
>> // NOTE: if we accept Qt::Vertical, the program displays what should
>> // be column headings in the left column as row headings!!!
>> if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
>> {
>
> Seems OK to me - it returns the column headers to display. If
> orientation == Qt::Vertical the view is asking for the row "headers".
> Are you sure you didn't confuse horizontal and vertical for a moment?
>
> HTH, Martin
>
> This part of your problem may be due to no column being defined, thus no
> cells are there to be filled with data.
So, where am I not defining columns? columnCount returns something
definitely > 0, though as you point out, it may be shy of the actual
count by 1. That was a "grasping at straws" effort on my part to fix
something else, I will take that out.
Here is what happens: when I leave the line
if (orientation == Qt::Horizontal
in the headerData() method, the table view has no data displayed and
tiny little boxes along the left border where row labels should be. The
number of rows is equal to rowCount(), so that must be working OK. If I
change that line to
if (orientation == Qt::Vertical,
I get an empty table, with the column labels arranged as row headings in
what were empty boxes with Qt::Horizontal.
This is really perplexing. I appreciate your comment about the meaning
of Qt::Vertical and Qt::Horizontal, but still it does not behave correctly.
Something silly, but what is it??
--
[ signature omitted ]
Message 4 in thread
> Here is what happens: when I leave the line
> if (orientation == Qt::Horizontal
> in the headerData() method, the table view has no data displayed and
> tiny little boxes along the left border where row labels should be. The
> number of rows is equal to rowCount(), so that must be working OK. If I
> change that line to
> if (orientation == Qt::Vertical,
> I get an empty table, with the column labels arranged as row headings in
> what were empty boxes with Qt::Horizontal.
>
> This is really perplexing. I appreciate your comment about the meaning
> of Qt::Vertical and Qt::Horizontal, but still it does not behave correctly.
Sorry, this was not meant to embarass you; just to make sure...
Yes, these symptoms are strange indeed; these things work without
problems in 4.1.x. What I would do is to "dumb down" my model, in this
case especially headerData(), to return fixed values, and then check
where the problem may hide.
Martin
--
[ signature omitted ]
Message 5 in thread
Martin Gebert wrote:
>> Here is what happens: when I leave the line
>> if (orientation == Qt::Horizontal
>> in the headerData() method, the table view has no data displayed and
>> tiny little boxes along the left border where row labels should be.
>> The number of rows is equal to rowCount(), so that must be working OK.
>> If I change that line to
>> if (orientation == Qt::Vertical,
>> I get an empty table, with the column labels arranged as row headings
>> in what were empty boxes with Qt::Horizontal.
>>
>> This is really perplexing. I appreciate your comment about the meaning
>> of Qt::Vertical and Qt::Horizontal, but still it does not behave
>> correctly.
>
> Sorry, this was not meant to embarass you; just to make sure...
> Yes, these symptoms are strange indeed; these things work without
> problems in 4.1.x. What I would do is to "dumb down" my model, in this
> case especially headerData(), to return fixed values, and then check
> where the problem may hide.
>
> Martin
>
I dumbed down the model, got the row and column headers to work OK, but
now the data() method is not being called at all, except ToolTipRole
once the table is fully in view. I have tried calling reset() on the
TableView, no effect. What would inhibit the data() method from being
called?
--
[ signature omitted ]
Message 6 in thread
> I dumbed down the model, got the row and column headers to work OK, but
> now the data() method is not being called at all, except ToolTipRole
> once the table is fully in view. I have tried calling reset() on the
> TableView, no effect. What would inhibit the data() method from being
> called?
Except from having the wrong method signature in your implementation (e.
g. a forgotten const, but that would cause a compiler error as
QAbstractItemModel::data() is pure virtual) I could think of no rows or
columns being defined (yes, we already excluded that), and perhaps wrong
flags (comment that out and rely on the default implementation for a test).
Or did you tweak something in the view or delegate that could possibly
cause this? Else I'm out of ideas now, except for "check everything, let
settle for some days, check again, repeat until it bites you". Or build
a new model from scratch, bit by bit with testing after each addition...
Good luck!
Martin
--
[ signature omitted ]
Message 7 in thread
Martin Gebert wrote:
>> I dumbed down the model, got the row and column headers to work OK,
>> but now the data() method is not being called at all, except
>> ToolTipRole once the table is fully in view. I have tried calling
>> reset() on the TableView, no effect. What would inhibit the data()
>> method from being called?
>
> Except from having the wrong method signature in your implementation (e.
> g. a forgotten const, but that would cause a compiler error as
> QAbstractItemModel::data() is pure virtual) I could think of no rows or
> columns being defined (yes, we already excluded that), and perhaps wrong
> flags (comment that out and rely on the default implementation for a test).
> Or did you tweak something in the view or delegate that could possibly
> cause this? Else I'm out of ideas now, except for "check everything, let
> settle for some days, check again, repeat until it bites you". Or build
> a new model from scratch, bit by bit with testing after each addition...
> Good luck!
>
> Martin
>
OK, it's fixed. Turned out a list of variables was being reset to 0
after an averaging operation, causing the model to report a columnCount
of 0. I made the list static, took care of it. I knew it would be
something silly....
Thanks for your help.
--
[ signature omitted ]