一、主窗体框架用到的函数
mainwindow.h中源码:
#ifndef HISTOGRAMVIEW_H
#define HISTOGRAMVIEW_H
#include <QAbstractItemView>
#include <QItemSelectionModel>
#include <QRegion>
#include <QMouseEvent>
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;
};
#endif // HISTOGRAMVIEW_H
mainwindow.cpp中源码:
#include "mainwindow.h"
#include <QItemSelectionModel>
#include <QFileDialog>
#include <QFile>
#include <QTextStream>
#include <QStringList>
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()
{
/*
table = new QTableView; //新建一个QTableView对象
table->setModel(model); //为QTableView对象设置相同的Model
QItemSelectionModel *selectionModel=new QItemSelectionModel(model);
//(a)
table->setSelectionModel(selectionModel);
connect(selectionModel,SIGNAL(selectionChanged(QItemSelection, ItemSelection)),table,SLOT(selectionChanged(QItemSelection,QItemSelection))); //(b)
splitter = new QSplitter;
splitter->setOrientation(Qt::Vertical);
splitter->addWidget(table);
setCentralWidget(splitter);
*/
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();
}
}
}
二、数据表格的加载和柱状图的绘制
自定义一个HistogramView类,继承自QAbstractItem类,用于对表格数据进行柱状图的显示。
histogramview.h中代码:
#ifndef HISTOGRAMVIEW_H
#define HISTOGRAMVIEW_H
#include <QAbstractItemView>
#include <QItemSelectionModel>
#include <QRegion>
#include <QMouseEvent>
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;
};
#endif // HISTOGRAMVIEW_H
histogramview.cpp中源码:
#include "histogramview.h"
#include <QPainter>
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{
}
void HistogramView::scrollTo(const QModelIndex &index,ScrollHint){
}
QModelIndex HistogramView::moveCursor(QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers modifiers){
}
int HistogramView::horizontalOffset()const{
}
int HistogramView::verticalOffset()const{
}
bool HistogramView::isIndexHidden(const QModelIndex &index)const{
}
QRegion HistogramView::visualRegionForSelection(const QItemSelection & selection)const{
}
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;
}
三、运行效果
加载文件之后: