一个 QTableView 中的两个表

Posted

技术标签:

【中文标题】一个 QTableView 中的两个表【英文标题】:Two tables in one QTableView 【发布时间】:2015-10-20 09:19:17 【问题描述】:

现在有这样的视图:

第一列像 freezetablewidget 示例一样被冻结

我想创建这样的视图:

即两个 qabstractItemModel 的一个滚动条。第二张表是第一张表的平均值,最小值,最大值。 sqlite 数据库中的所有表。

【问题讨论】:

您是否尝试使用QAbstractProxyModel 合并您的两个模型? @RomhaKorev,不,我找不到任何关于我的问题的例子。如果它存在,你能告诉我吗? 见this question你可以使用QSqlQueryModel 【参考方案1】:

我创建了这个问题的解决方案:

freezetableview.h

#ifndef FREEZETABLEWIDGET_H
#define FREEZETABLEWIDGET_H

#include <QObject>
#include <QWidget>
#include <QTableView>
#include <QSortFilterProxyModel>

#include "backgroundcolordelegate.h"
#include "sortproxymodel.h"
//#include "colorabstractitemmodel.h"

class FreezeTableView : public QTableView

    Q_OBJECT
public:
    FreezeTableView(QWidget * parent = 0);
    FreezeTableView(QAbstractItemModel * model);
    ~FreezeTableView();
    void init();
    void setModel(QAbstractItemModel *model);



protected:
    virtual void resizeEvent(QResizeEvent *event);
    virtual QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers);
    void scrollTo (const QModelIndex & index, ScrollHint hint = EnsureVisible);


private:
//      void init();
      void updateFrozenTableGeometry();


private slots:
    void updateSectionWidth(int logicalIndex, int oldSize, int newSize);
    void updateSectionHeight(int logicalIndex, int oldSize, int newSize);

public:
    QTableView *m_mathTableView;

private:
    QTableView          *m_frozenTableView;
    SortProxyModel      *m_sortModel;
//    QAbstractItemModel  *m_model;
      //      ColorAbstractItemModel *itemModel;
;

#endif // FREEZETABLEWIDGET_H

freezetableview.cpp

#include "freezetableview.h"

#include <QScrollBar>
#include <QHeaderView>
#include <QStandardItemModel>
#include <QSortFilterProxyModel>

FreezeTableView::FreezeTableView(QWidget * parent)
    :QTableView(parent)

//    m_model = new QStandardItemModel(0,3,this);
//    m_sortModel = new SortProxyModel(this);
//    sortModel->setSourceModel(new QStandardItemModel(0,3,this));
//    m_sortModel->setSourceModel(m_model);
//    m_sortModel->setDynamicSortFilter(true);
//    m_frozenTableView->setModel(m_sortModel);

    m_sortModel = new SortProxyModel(this);
    //work
    setModel( new QStandardItemModel(0,3,this));
    m_frozenTableView = new QTableView(this);
    m_mathTableView = new QTableView(this);
    //

    init();

    //connect the headers and scrollbars of both tableviews together
    connect(horizontalHeader(),SIGNAL(sectionResized(int,int,int)), this,
            SLOT(updateSectionWidth(int,int,int)));
    connect(verticalHeader(),SIGNAL(sectionResized(int,int,int)), this,
            SLOT(updateSectionHeight(int,int,int)));

    connect(m_frozenTableView->verticalScrollBar(), SIGNAL(valueChanged(int)),
            verticalScrollBar(), SLOT(setValue(int)));
    connect(verticalScrollBar(), SIGNAL(valueChanged(int)),
            m_frozenTableView->verticalScrollBar(), SLOT(setValue(int)));

//    connect(mathTableView->verticalScrollBar(), SIGNAL(valueChanged(int)),
//            verticalScrollBar(), SLOT(setValue(int)));
//    connect(verticalScrollBar(), SIGNAL(valueChanged(int)),
//            mathTableView->verticalScrollBar(), SLOT(setValue(int)));

    connect(m_mathTableView->horizontalScrollBar(), SIGNAL(valueChanged(int)),
            horizontalScrollBar(), SLOT(setValue(int)));
    connect(horizontalScrollBar(), SIGNAL(valueChanged(int)),
            m_mathTableView->horizontalScrollBar(), SLOT(setValue(int)));

    BackgroundColorDelegate *delegate = new BackgroundColorDelegate(this);
    this->setItemDelegate(delegate);


FreezeTableView::FreezeTableView(QAbstractItemModel * model)

    // не вызывается
    qDebug("FreezeTableView::FreezeTableView(QAbstractItemModel * model) opening!!!" );
    setModel(model);
    m_frozenTableView = new QTableView(this);

    init();

    //connect the headers and scrollbars of both tableviews together
    connect(horizontalHeader(),SIGNAL(sectionResized(int,int,int)), this,
          SLOT(updateSectionWidth(int,int,int)));
    connect(verticalHeader(),SIGNAL(sectionResized(int,int,int)), this,
          SLOT(updateSectionHeight(int,int,int)));

    connect(m_frozenTableView->verticalScrollBar(), SIGNAL(valueChanged(int)),
          verticalScrollBar(), SLOT(setValue(int)));
    connect(verticalScrollBar(), SIGNAL(valueChanged(int)),
          m_frozenTableView->verticalScrollBar(), SLOT(setValue(int)));

    //      BackgroundColorDelegate *delegate = new BackgroundColorDelegate();
    //      this->setItemDelegate(delegate);


FreezeTableView::~FreezeTableView()

    delete m_frozenTableView;
    delete m_mathTableView;
    if(m_sortModel != NULL)
    
        delete m_sortModel;
    
//    delete m_model;


void FreezeTableView::init()

    m_frozenTableView->setModel(model());
    m_frozenTableView->setFocusPolicy(Qt::NoFocus);
    m_frozenTableView->verticalHeader()->hide();
    m_frozenTableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);

    //mathTableView->setModel(model());
    m_mathTableView->setFocusPolicy(Qt::NoFocus);
    m_mathTableView->verticalHeader()->hide();
    m_mathTableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);

    viewport()->stackUnder(m_mathTableView);
    viewport()->stackUnder(m_frozenTableView);


//      frozenTableView->setStyleSheet("QTableView  border: none;"
//                                     "background-color: #8EDE21;"
//                                     "selection-background-color: #999"); //for demo purposes
    m_frozenTableView->setSelectionModel(selectionModel());
    for (int col = 1; col < model()->columnCount(); ++col)
        m_frozenTableView->setColumnHidden(col, true);

    m_frozenTableView->setColumnWidth(0, columnWidth(0) );

    m_frozenTableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_frozenTableView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    setHorizontalScrollMode(ScrollPerPixel);
    setVerticalScrollMode(ScrollPerPixel);
    m_frozenTableView->setVerticalScrollMode(ScrollPerPixel);

    //mathTableView
//    mathTableView->setSelectionModel(selectionModel());

    m_mathTableView->setColumnWidth(0, columnWidth(0) );

    m_mathTableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_mathTableView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    setHorizontalScrollMode(ScrollPerPixel);
    setVerticalScrollMode(ScrollPerPixel);
    m_mathTableView->setVerticalScrollMode(ScrollPerPixel);

    m_mathTableView->show();
    m_frozenTableView->show();

    updateFrozenTableGeometry();



void FreezeTableView::updateSectionWidth(int logicalIndex, int /* oldSize */, int newSize)

    m_mathTableView->setColumnWidth(logicalIndex, newSize);
    if (logicalIndex == 0)
        m_frozenTableView->setColumnWidth(0, newSize);
    
    updateFrozenTableGeometry();


void FreezeTableView::updateSectionHeight(int logicalIndex, int /* oldSize */, int newSize)

    m_frozenTableView->setRowHeight(logicalIndex, newSize);



void FreezeTableView::resizeEvent(QResizeEvent * event)

      QTableView::resizeEvent(event);
      updateFrozenTableGeometry();


QModelIndex FreezeTableView::moveCursor(CursorAction cursorAction,
                                          Qt::KeyboardModifiers modifiers)

    QModelIndex current = QTableView::moveCursor(cursorAction, modifiers);

    if (cursorAction == MoveLeft && current.column() > 0
          && visualRect(current).topLeft().x() < m_frozenTableView->columnWidth(0) )
        const int newValue = horizontalScrollBar()->value() + visualRect(current).topLeft().x()
                             - m_frozenTableView->columnWidth(0);
        horizontalScrollBar()->setValue(newValue);
        m_mathTableView->horizontalScrollBar()->setValue(newValue);
    
    return current;


void FreezeTableView::scrollTo (const QModelIndex & index, ScrollHint hint)
    if (index.column() > 0)
        QTableView::scrollTo(index, hint);


void FreezeTableView::updateFrozenTableGeometry()

    int frameWidthh = frameWidth();
    int columnWidth0 = columnWidth(0);
    int viewportHeight = viewport()->height();
    int viewportWidth = viewport()->width();
    int horizontalHeaderHeight = horizontalHeader()->height();
    int horizontalHeaderWidth  = horizontalHeader()->width();
    int verticalHeaderHeight = verticalHeader()->height();
    int verticalHeaderWidth = verticalHeader()->width();
    int mathTableViewHeight = m_mathTableView->height();

    m_frozenTableView->setGeometry(verticalHeaderWidth + frameWidthh,
                               frameWidthh,
                               columnWidth0,
                               viewportHeight+horizontalHeaderHeight);
    m_mathTableView->setGeometry(verticalHeaderWidth + frameWidthh,
                             frameWidthh + horizontalHeaderHeight + viewportHeight - mathTableViewHeight,
                             viewportWidth,
                             mathTableViewHeight);


void FreezeTableView::setModel(QAbstractItemModel *model)

    m_sortModel = new SortProxyModel(this);
    m_sortModel->setSourceModel(model);
    QTableView::setModel(m_sortModel);

【讨论】:

以上是关于一个 QTableView 中的两个表的主要内容,如果未能解决你的问题,请参考以下文章

一个 QTableView 中的两个表

QT - QTableView removeRow() 崩溃

如何在 Pyqt4 中设置 QTableView 标头名称

PyQt,Qtable在启用排序时清除列

如何在pyqt4的右侧对齐qtableview行?

QT QTableView(基于QStandardItemModel用法)操作详解