• 13477阅读
  • 15回复

QTableView实现行列互换 [复制链接]

上一主题 下一主题
离线kenby
 
只看楼主 倒序阅读 楼主  发表于: 2009-07-27
— 本帖被 XChinux 从 General Qt Programming 移动到本区(2011-01-02) —
用QTableView和QSqlTableModel从表model_detail读取一行数据显示,效果如下图
http://kenby.javaeye.com/upload/picture/pic/41116/c3543b46-3b28-3acc-b93d-b3840335483e.png
由于只有一行数据,且字段很多,所以我想让它这样显示,如下图:
http://kenby.javaeye.com/upload/picture/pic/41114/d1b56f4b-b35c-3229-88ee-b07a724a47e7.png
请问如何做到?相关代码如下:
  1. standardView = new QTableView;
  2. standardModel = new QSqlTableModel;
  3. standardModel->setTable("model_detail");
  4. standardModel->select();
  5. standardView->setModel(standardModel);
  6. standardView->show();
[ 此帖被kenby在2009-07-29 10:51重新编辑 ]
离线yokykk
只看该作者 1楼 发表于: 2009-07-27
图片不能用,是不是实现行列转换啊,我也遇到同样的问题,急求答案,谢谢!!!
离线kenby
只看该作者 2楼 发表于: 2009-07-27
是啊,图片换成链接了,这个问题应该可以解决吧,但试了好多次没找到方法
离线yleesun

只看该作者 3楼 发表于: 2009-07-28
用自定义model.
1.从数据库中读出数据。
2.设置自定义model数据源
3.给tableview设置model。
自定义model,根据自己愿望组织列。
离线yokykk
只看该作者 4楼 发表于: 2009-07-28
继承 QAbstractProxyModel,实现一个新的代理类,在其中涉及到row和col的函数做下处理(行列互换),
然后用 setSourceModel将原来的model替换掉
离线kenby
只看该作者 5楼 发表于: 2009-07-29
楼上的兄台,你的思路懂了,能不能把代码贴上来
离线kenby
只看该作者 6楼 发表于: 2009-07-29
楼主兄弟,还是我来告诉你吧,正如楼上的楼上所说, 定义一个RotatedProxyModel代理类:
rotatedproxymodel.h文件
  1. #ifndef ROTATEDPROXYMODEL_H
  2. #define ROTATEDPROXYMODEL_H
  3. #include <QAbstractProxyModel>
  4. class QAbstractTableModel;
  5. // 交换行和列的代理model
  6. class RotatedProxyModel : public QAbstractProxyModel
  7. {
  8.         Q_OBJECT
  9.     public:
  10.         RotatedProxyModel( QObject* parent );
  11.         ~RotatedProxyModel();
  12.         virtual QModelIndex index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const;
  13.         virtual QModelIndex mapFromSource ( const QModelIndex & sourceIndex ) const;
  14.         virtual QModelIndex mapToSource ( const QModelIndex & proxyIndex ) const;
  15.         virtual void setSourceModel( QAbstractTableModel* sourceModel );
  16.         virtual int columnCount ( const QModelIndex & parent = QModelIndex() ) const;
  17.         virtual QModelIndex parent ( const QModelIndex & index ) const;
  18.         virtual int rowCount ( const QModelIndex & parent = QModelIndex() ) const;
  19.         virtual QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
  20.         virtual bool setHeaderData ( int section, Qt::Orientation orientation, const QVariant & value, int role = Qt::EditRole );
  21. };
  22. #endif

rotatedproxymodel.cpp文件
  1. #include "rotatedproxymodel.h"
  2. RotatedProxyModel::RotatedProxyModel( QObject* parent ): QAbstractProxyModel( parent )
  3. {
  4. }
  5. RotatedProxyModel::~RotatedProxyModel()
  6. {
  7. }
  8. void RotatedProxyModel::setSourceModel( QAbstractTableModel* sourceModel )
  9. {
  10.     QAbstractProxyModel::setSourceModel(sourceModel);
  11. }
  12. int RotatedProxyModel::columnCount( const QModelIndex & parent ) const
  13. {
  14.     if( parent.isValid() )
  15.         return 0;
  16.     if( sourceModel() )
  17.         return sourceModel()->rowCount( );    /* 代理model的columnCount等于sourceModel的rowCount */
  18.     else
  19.         return 0;
  20. }
  21. QModelIndex RotatedProxyModel::parent( const QModelIndex & index ) const
  22. {
  23.     if( sourceModel() )
  24.         return sourceModel()->parent(index);
  25.     else
  26.         return QModelIndex();
  27. }
  28. int RotatedProxyModel::rowCount( const QModelIndex & parent ) const
  29. {
  30.     if( parent.isValid() )
  31.         return 0;
  32.     if( sourceModel() )
  33.         return sourceModel()->columnCount( ); /* 代理model的rowCount等于sourceModel的columnCount */
  34.     else
  35.         return 0;
  36. }
  37. QModelIndex RotatedProxyModel::mapFromSource( const QModelIndex & sourceIndex ) const
  38. {
  39.     if( sourceModel() )
  40.         return sourceModel()->index( sourceIndex.column(), sourceIndex.row(), sourceIndex.parent() );
  41.     else
  42.         return QModelIndex();
  43. }
  44. QModelIndex RotatedProxyModel::mapToSource( const QModelIndex & proxyIndex ) const
  45. {
  46.     if( sourceModel() )
  47.         return sourceModel()->index( proxyIndex.column(), proxyIndex.row(), proxyIndex.parent() );
  48.     else
  49.         return QModelIndex();
  50. }
  51. QModelIndex RotatedProxyModel::index( int row, int column, const QModelIndex & parent ) const
  52. {
  53.     if( sourceModel() )
  54.         return sourceModel()->index( column, row, parent );
  55.     else
  56.         return QModelIndex();
  57. }
  58. QVariant RotatedProxyModel::headerData( int section, Qt::Orientation orientation, int role ) const
  59. {
  60.     if( orientation == Qt::Horizontal )
  61.         return sourceModel()->headerData( section, Qt::Vertical, role );
  62.     else
  63.         return sourceModel()->headerData( section, Qt::Horizontal, role );
  64. }
  65. bool RotatedProxyModel::setHeaderData( int section, Qt::Orientation orientation, const QVariant & value, int role )
  66. {
  67.     if( orientation == Qt::Horizontal )
  68.         return sourceModel()->setHeaderData( section, Qt::Vertical, value, role );
  69.     else
  70.         return sourceModel()->setHeaderData( section, Qt::Horizontal, value, role );
  71. }


使用这个类的方法:
  1. standardView = new QTableView;
  2. QSqlTableModel *sourceModel = new QSqlTableModel;
  3. sourceModel->setTable("model_group");
  4. sourceModel->select();
  5. standardModel = new RotatedProxyModel(this);
  6. standardModel->setSourceModel(sourceModel);
  7. standardView->setModel(standardModel);
;
离线yokykk
只看该作者 7楼 发表于: 2009-07-29
今天测试使用代理还有个问题,显示是没有问题的,但是使用QsqlRelationalTableModel,对row增加和删除时,表头不能刷新。。。。
试了一些方法还是没有解决,不知各位有什么好的方法??
表头刷新是在HeaderView中完成,感觉用代理实现行列互换仅仅可以实现显示,完整的sqlt model功能,比如增、删等处理靠代理还是不能完美解决。
离线kenby
只看该作者 8楼 发表于: 2009-07-29
楼上所言甚是,我也正在为这个问题苦恼。。。觉得qt对数据库管理功能支持不是很灵活啊
离线kenby
只看该作者 9楼 发表于: 2009-07-29
网上找到一个解决方案,经测试,可以完美解决行列互换的问题,代码如下:
rotatedproxymodel.h
  1. #include <QAbstractProxyModel>
  2. class RotatedProxyModel : public QAbstractProxyModel
  3. {
  4. public:
  5.     RotatedProxyModel(QObject *p = 0) : QAbstractProxyModel(p){}
  6.     QModelIndex mapFromSource ( const QModelIndex & sourceIndex ) const
  7.     {
  8.         return index(sourceIndex.column(), sourceIndex.row());
  9.     }
  10.     QModelIndex mapToSource ( const QModelIndex & proxyIndex ) const
  11.     {
  12.         return sourceModel()->index(proxyIndex.column(), proxyIndex.row());
  13.     }
  14.     QModelIndex index(int r, int c, const QModelIndex &ind=QModelIndex()) const
  15.     {
  16.         return createIndex(r,c);
  17.     }
  18.     QModelIndex parent(const QModelIndex&) const
  19.     {
  20.         return QModelIndex();
  21.     }
  22.     int rowCount(const QModelIndex &) const
  23.     {
  24.         return sourceModel()->columnCount();
  25.     }
  26.     int columnCount(const QModelIndex &) const
  27.     {
  28.         return sourceModel()->rowCount();
  29.     }
  30.     QVariant data(const QModelIndex &ind, int role) const
  31.     {
  32.         return sourceModel()->data(mapToSource(ind), role);
  33.     }
  34.     QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const
  35.     {
  36.         if( orientation == Qt::Horizontal )
  37.             return sourceModel()->headerData( section, Qt::Vertical, role );
  38.         else
  39.             return sourceModel()->headerData( section, Qt::Horizontal, role );
  40.     }
  41.     bool setHeaderData( int section, Qt::Orientation orientation, const QVariant & value, int role = Qt::DisplayRole )
  42.     {
  43.         if( orientation == Qt::Horizontal )
  44.             return sourceModel()->setHeaderData( section, Qt::Vertical, value, role );
  45.         else
  46.             return sourceModel()->setHeaderData( section, Qt::Horizontal, value, role );
  47.     }
  48. };

使用方法:
  1. standardView = new QTableView;
  2. QSqlTableModel *sourceModel = new QSqlTableModel;
  3. sourceModel->setTable("model_group");
  4. sourceModel->select();
  5. sourceModel->setEditStrategy(QSqlTableModel::OnRowChange);
  6. standardModel = new RotatedProxyModel;
  7. standardModel->setSourceModel(sourceModel);
  8. standardView->setModel(standardModel);
[ 此帖被kenby在2009-07-30 01:19重新编辑 ]
离线yokykk
只看该作者 10楼 发表于: 2009-07-30
明天去公司试试楼上的方法,希望可以吧
关键是能深层次理解代理的机制.....
离线yokykk
只看该作者 11楼 发表于: 2009-07-31
用了以上方法还是解决不了表头刷新问题,楼主能不能把完整测试代码给出来,看下你是怎么实现列选删除和增加的,谢谢!!!
离线kenby
只看该作者 12楼 发表于: 2009-07-31
表头刷新是什么问题?
离线yokykk
只看该作者 13楼 发表于: 2009-07-31
就是在行列互换后,选中几列数据进行删除,数据删除后表格内容已经更新,但是表头没有刷新
比如:原来有10列数据,在界面上点击选中三列,然后调用removeColumns()进行数据删除,删除后表格中已经变为7条记录,但是表头上面还是显示1至10。
你的测试代码中包含选中删除操作吗?是怎么实现的?
能不能把整个测试代码发上来看下
离线kenby
只看该作者 14楼 发表于: 2009-08-01
这个问题我也不知道怎么办,看来只好你自己探索了
离线aifei7320

只看该作者 15楼 发表于: 2014-11-14
九楼的方法帮了大忙了,不过这些东西如何才能想到呢?如何才能深入到类之间,如何才能随心所欲的驾驭这些类。
快速回复
限100 字节
 
上一个 下一个