QT:模型视图结构----View

柱状图类 声明:

class HistogramView : public QAbstractItemView
{
    Q_OBJECT
public:
    HistogramView(QWidget *parent=0);
    //虚函数声明                                         //(a)
    QRect visualRect(const QModelIndex &index)const;
    void scrollTo(const QModelIndex &index,ScrollHint hint= EnsureVisible);
    QModelIndex indexAt(const QPoint &point)const;      //(b)

    //为selections赋初值
    void setSelectionModel(QItemSelectionModel *selectionModel);
    QRegion itemRegion(QModelIndex index);
    void paintEvent(QPaintEvent *);
    void mousePressEvent(QMouseEvent *event);           //(c)

protected slots:
    void selectionChanged(const QItemSelection &selected,
    const QItemSelection &deselected);          //(d)
    void dataChanged(const QModelIndex &topLeft,
    const QModelIndex &bottomRight);                //(e)

protected:
    //虚函数声明
    QModelIndex moveCursor(QAbstractItemView::CursorAction cursorAction,Qt::KeyboardModifiers modifiers);
    int horizontalOffset()const;
    int verticalOffset()const;
    bool isIndexHidden(const QModelIndex &index)const;
    void setSelection(const QRect &rect,QItemSelectionModel:: SelectionFlags flags);//(f)
    QRegion visualRegionForSelection(const QItemSelection &selection) const;

private:
    QItemSelectionModel *selections;                    //(g)
    QList<QRegion> MRegionList;                         //(h)
    QList<QRegion> FRegionList;
    QList<QRegion> SRegionList;
};

柱状图类 实现:

HistogramView::HistogramView(QWidget *parent):QAbstractItemView(parent)
{

}
// paintEvent()函数具体完成柱状统计图绘制的工作
void HistogramView::paintEvent(QPaintEvent *)
{
    QPainter painter(viewport());                   //(a)
    painter.setPen(Qt::black);
    int x0=40;
    int y0=250;
    /* 完成了x、y坐标轴的绘制,并标注坐标轴的变量 */
    //y坐标轴
    painter.drawLine(x0,y0,40,30);
    painter.drawLine(38,32,40,30);
    painter.drawLine(40,30,42,32);
    painter.drawText(20,30,tr("人数"));
    for(int i=1;i<5;i++)
    {
        painter.drawLine(-1,-i*50,1,-i*50);
        painter.drawText(-20,-i*50,tr("%1").arg(i*5));
    }
    //x 坐标轴
    painter.drawLine(x0,y0,540,250);
    painter.drawLine(538,248,540,250);
    painter.drawLine(540,250,538,252);
    painter.drawText(545,250,tr("部门"));
    int posD=x0+20;
    int row;
    for(row=0;row<model()->rowCount(rootIndex());row++)
    {
        QModelIndex index=model()->index(row,0,rootIndex());
        QString dep=model()->data(index).toString();
        painter.drawText(posD,y0+20,dep);
        posD+=50;
    }
    /* 完成了表格第1列数据的柱状统计图的绘制 */
    //男
    int posM=x0+20;
    MRegionList.clear();
    for(row=0;row<model()->rowCount(rootIndex());row++)
    {
        QModelIndex index = model()->index(row,1,rootIndex());

        int male = model()->data(index).toDouble();
        int width=10;

        if(selections->isSelected(index))           //(b)
            painter.setBrush(QBrush(Qt::blue,Qt::Dense3Pattern));
        else
            painter.setBrush(Qt::blue);

        painter.drawRect(QRect(posM,y0-male*10,width,male*10));//(c)

        QRegion regionM(posM,y0-male*10,width,male*10);
        MRegionList.insert(row,regionM);            //(d)

        posM+=50;
    }
    /* 完成了表格第2列数据的柱状统计图的绘制 */           //(e)
    //女
    int posF=x0+30;
    FRegionList.clear();
    for(row=0;row<model()->rowCount(rootIndex());row++)
    {
        QModelIndex index=model()->index(row,2,rootIndex());
        int female=model()->data(index).toDouble();
        int width=10;
        if(selections->isSelected(index))
            painter.setBrush(QBrush(Qt::red,Qt::Dense3Pattern));
        else
            painter.setBrush(Qt::red);
        painter.drawRect(QRect(posF,y0-female*10,width,female*10));
        QRegion regionF(posF,y0-female*10,width,female*10);
        FRegionList.insert(row,regionF);
        posF+=50;
    }
    /* 完成了表格第3列数据的柱状统计图的绘制 */           //(f)
    //退休
    int posS=x0+40;
    SRegionList.clear();
    for(row=0;row<model()->rowCount(rootIndex());row++)
    {
        QModelIndex index=model()->index(row,3,rootIndex());
        int retire=model()->data(index).toDouble();
        int width=10;
        if(selections->isSelected(index))
            painter.setBrush(QBrush(Qt::green,Qt::Dense3Pattern));
        else
            painter.setBrush(Qt::green);
        painter.drawRect(QRect(posS,y0-retire*10,width,retire*10));
        QRegion regionS(posS,y0-retire*10,width,retire*10);
        SRegionList.insert(row,regionS);
        posS+=50;
    }
}
void HistogramView::dataChanged(const QModelIndex &topLeft,
                                const QModelIndex &bottomRight)
{
    QAbstractItemView::dataChanged(topLeft,bottomRight);
    viewport()->update();
}
void HistogramView::setSelectionModel(QItemSelectionModel *selectionModel)
{
    selections=selectionModel;
}
void HistogramView::selectionChanged(const QItemSelection &selected,
                                     const QItemSelection &deselected)
{
    viewport()->update();
}
void HistogramView::mousePressEvent(QMouseEvent *event)
{
    QAbstractItemView::mousePressEvent(event);
    setSelection(QRect(event->pos().x(),event->pos().y(),1,1),QItemSelectionModel::SelectCurrent);
}
void HistogramView::setSelection(const QRect &rect,QItemSelectionModel::SelectionFlags flags)
{
    int rows = model()->rowCount(rootIndex());          //获取总行数
    int columns = model()->columnCount(rootIndex());    //获取总列数
    QModelIndex selectedIndex;                          //(a)
    for (int row=0; row<rows; ++row)                    //(b)
    {
        for (int column=1; column<columns; ++column)
        {
            QModelIndex index=model()->index(row,column,rootIndex());
            QRegion region=itemRegion(index);           //(c)
            if (!region.intersected(rect).isEmpty())
                selectedIndex = index;
        }
    }
    if(selectedIndex.isValid())                         //(d)
        selections->select(selectedIndex,flags);
    else
    {
        QModelIndex noIndex;
        selections->select(noIndex,flags);
    }
}
QModelIndex HistogramView::indexAt(const QPoint &point)const
{
    QPoint newPoint(point.x(),point.y());
    QRegion region;
    // 男 列
    foreach(region,MRegionList)                         //(a)
    {
        if (region.contains(newPoint))
        {
            int row = MRegionList.indexOf(region);
            QModelIndex index = model()->index(row,1,rootIndex());
            return index;
        }
    }
    // 女 列
    foreach(region,FRegionList)                         //(b)
    {
        if (region.contains(newPoint))
        {
            int row = FRegionList.indexOf(region);
            QModelIndex index = model()->index(row,2,rootIndex());
            return index;
        }
    }
    // 合计 列
    foreach(region,SRegionList)                         //(c)
    {
        if (region.contains(newPoint))
        {
            int row = SRegionList.indexOf(region);
            QModelIndex index = model()->index(row,3,rootIndex());
            return index;
        }
    }
    return QModelIndex();
}

QRect HistogramView::visualRect(const QModelIndex &index)const{return QRect(0,0,1,1);}
void HistogramView::scrollTo(const QModelIndex &index,ScrollHint){}
QModelIndex HistogramView::moveCursor(QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers modifiers){QModelIndex indx;  return indx; }
int HistogramView::horizontalOffset()const{return 0;}
int HistogramView::verticalOffset()const{return 0;}
bool HistogramView::isIndexHidden(const QModelIndex &index)const{return false;}
QRegion HistogramView::visualRegionForSelection(const QItemSelection & selection)const{QRegion region; return region;}

QRegion HistogramView::itemRegion(QModelIndex index)
{
    QRegion region;
    if (index.column() == 1)        //男
        region = MRegionList[index.row()];
    if (index.column() == 2)        //女
        region = FRegionList[index.row()];
    if (index.column() == 3)        //退休
        region = SRegionList[index.row()];
    return region;
}

窗口 声明:

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void createAction();
    void createMenu();
    void setupModel();
    void setupView();
    void openFile(QString);
    public slots:
        void slotOpen();
private:
    QMenu *fileMenu;
    QAction *openAct;
    QStandardItemModel *model;
    QTableView *table;
    QSplitter *splitter;
    HistogramView *histogram;
};

窗口 实现:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    createAction();
    createMenu();
    setupModel();
    setupView();
    setWindowTitle(tr("View Example"));
    resize(600,600);
}

MainWindow::~MainWindow()
{

}
void MainWindow::createAction()
{
    openAct = new QAction(tr("打开"),this);
    connect(openAct,SIGNAL(triggered()),this,SLOT(slotOpen()));
}
void MainWindow::createMenu()
{
    fileMenu = new QMenu(tr("文件"),this);
    fileMenu->addAction(openAct);
    menuBar()->addMenu(fileMenu);
}
void MainWindow::setupModel()
{
    model = new QStandardItemModel(4,4,this);
    model->setHeaderData(0,Qt::Horizontal,tr("部门"));
    model->setHeaderData(1,Qt::Horizontal,tr("男"));
    model->setHeaderData(2,Qt::Horizontal,tr("女"));
    model->setHeaderData(3,Qt::Horizontal,tr("退休"));
}
void MainWindow::setupView()
{
    splitter = new QSplitter;
    splitter->setOrientation(Qt::Vertical);

    histogram = new HistogramView(splitter);        //新建一个HistogramView对象
    histogram->setModel(model);                     //为HistogramView对象设置相同的Model
    table = new QTableView;
    table->setModel(model);
    QItemSelectionModel *selectionModel=new QItemSelectionModel (model);
    table->setSelectionModel(selectionModel);
    histogram->setSelectionModel(selectionModel);   //(a)

    splitter->addWidget(table);
    splitter->addWidget(histogram);
    setCentralWidget(splitter);
    connect(selectionModel,SIGNAL(selectionChanged(QItemSelection,QItemSelection)),table,SLOT(selectionChanged(QItemSelection,QItemSelection)));
    connect(selectionModel,SIGNAL(selectionChanged(QItemSelection,QItemSelection)),histogram,SLOT(selectionChanged(QItemSelection,QItemSelection)));                                //(b)
}
void MainWindow::slotOpen()
{
    QString name;
    name = QFileDialog::getOpenFileName(this,"打开",".","histogram files (*.txt)");
    if (!name.isEmpty())
          openFile(name);
}
void MainWindow::openFile(QString path)
{
    if (!path.isEmpty())
    {
        QFile file(path);
         if (file.open(QFile::ReadOnly | QFile::Text))
         {
             QTextStream stream(&file);
             QString line;
             model->removeRows(0,model->rowCount(QModelIndex()),
                   QModelIndex());
             int row = 0;
             do
             {
                 line = stream.readLine();
                 if (!line.isEmpty())
                 {
                        model->insertRows(row, 1, QModelIndex());
                        QStringList pieces = line.split(",", QString
                            ::SkipEmptyParts);
                        model->setData(model->index(row, 0, QModelIndex()),
                            pieces.value(0));
                        model->setData(model->index(row, 1, QModelIndex()),
                            pieces.value(1));
                        model->setData(model->index(row, 2, QModelIndex()),
                            pieces.value(2));
                        model->setData(model->index(row,3, QModelIndex()),
                            pieces.value(3));
                        row++;
                 }
             } while (!line.isEmpty());
           file.close();
         }
    }
}

运行效果如下:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/u012061464/article/details/80706621