mainwindow
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QStandardItemModel>
#include <QTableView>
#include <QMenuBar>
#include <QMenu>
#include <QAction>
#include <QSplitter>
#include "histogramview.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~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;
};
#endif
mainwindow.cpp
#include "mainwindow.h"
#include <QHeaderView>
#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;
table->setModel(model);
table->horizontalHeader()->setStyleSheet("QHeaderView::section { background-color: #FFCCCC; }");
QItemSelectionModel *selectionModel = new QItemSelectionModel(model);
table->setSelectionModel(selectionModel);
connect(selectionModel,SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
table,SLOT(selectionChanged(QItemSelection,QItemSelection)));
splitter = new QSplitter;
splitter->setOrientation(Qt::Vertical);
histogram =new HistogramView(splitter);
histogram->setModel(model);
histogram->setSelectionModel(selectionModel);
splitter->addWidget(table);
splitter->addWidget(histogram);
setCentralWidget(splitter);
connect(selectionModel,SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
histogram,SLOT(selectionChanged(QItemSelection,QItemSelection)));
}
void MainWindow::openFile(QString path)
{
if(!path.isEmpty())
{
QFile file(path);
if(file.open(QFile::ReadOnly | QFile::Text))
{
QTextStream stream(&file);
stream.setCodec("UTF-8");
QString line;
model->removeRows(0,model->rowCount(QModelIndex()));
int row = 0;
do
{
line = stream.readLine();
if(!line.isEmpty())
{
model->insertRows(row,1,QModelIndex());
QStringList pleces = line.split(",");
model->setData(model->index(row,0,QModelIndex()),pleces.value(0));
model->setData(model->index(row,1,QModelIndex()),pleces.value(1));
model->setData(model->index(row,2,QModelIndex()),pleces.value(2));
model->setData(model->index(row,3,QModelIndex()),pleces.value(3));
row++;
}
}while(!stream.atEnd());
file.close();
}
}
}
void MainWindow::slotOpen()
{
QString name;
name = QFileDialog::getOpenFileName(this,"打开",".","histogram files (*.txt)");
if(!name.isEmpty())
{
openFile(name);
}
}
histogramview
histogramview.h
#ifndef HISTOGRAMVIEW_H
#define HISTOGRAMVIEW_H
#include <QAbstractItemView>
#include <QItemSelectionModel>
#include <QRegion>
#include <QMouseEvent>
#include <QPainter>
class HistogramView : public QAbstractItemView
{
Q_OBJECT
public:
HistogramView(QWidget *parent =0);
QRect visualRect(const QModelIndex &index)const{};
void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible){};
QModelIndex indexAt(const QPoint &point) const;
void setSelectionModel(QItemSelectionModel *selectionModel);
void paintEvent(QPaintEvent*);
void mousePressEvent(QMouseEvent*);
QRegion itemRegion(QModelIndex index);
protected slots:
void selectionChanged(const QItemSelection &selected,const QItemSelection &deselected);
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int>());
protected:
QModelIndex moveCursor(QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers modifiers){};
int horizontalOffset()const{return 0;};
int verticalOffset()const{return 0;};
bool isIndexHidden(const QModelIndex &index)const{return false;};
void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags flags);
QRegion visualRegionForSelection(const QItemSelection &selection) const{};
private:
QItemSelectionModel* selections;
QList<QRegion> MRegionList;
QList<QRegion> FRegionList;
QList<QRegion> SRegionList;
};
#endif
histogramview.cpp
#include "histogramview.h"
HistogramView::HistogramView(QWidget *parent):QAbstractItemView(parent)
{
}
QModelIndex HistogramView::indexAt(const QPoint &point) const
{
QPoint newPoint(point.x(),point.y());
QRegion region;
foreach (region, MRegionList)
{
if(region.contains(newPoint))
{
int row = MRegionList.indexOf(region);
QModelIndex index = model()->index(row,1,rootIndex());
return index;
}
}
foreach (region, FRegionList)
{
if(region.contains(newPoint))
{
int row = FRegionList.indexOf(region);
QModelIndex index = model()->index(row,2,rootIndex());
return index;
}
}
foreach (region, SRegionList)
{
if(region.contains(newPoint))
{
int row = SRegionList.indexOf(region);
QModelIndex index = model()->index(row,3,rootIndex());
return index;
}
}
return QModelIndex();
}
void HistogramView::setSelectionModel(QItemSelectionModel *selectionModel)
{
selections = selectionModel;
}
void HistogramView::paintEvent(QPaintEvent *)
{
QPainter painter(viewport());
painter.setPen(Qt::black);
int x0 = 40;
int y0 = 250;
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));
}
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;
}
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))
{
painter.setBrush(QBrush(Qt::blue,Qt::Dense3Pattern));
}else
{
painter.setBrush(Qt::blue);
}
painter.drawRect(QRect(posM,y0-male*10,width,male*10));
QRegion regionM(posM,y0-male*10,width,male*10);
MRegionList.insert(row,regionM);
posM +=50;
}
int posF =x0 +30;
FRegionList.clear();
for(row = 0;row<model()->rowCount(rootIndex());row++)
{
QModelIndex index =model()->index(row,2,rootIndex());
int male = 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-male*10,width,male*10));
QRegion regionF(posF,y0-male*10,width,male*10);
FRegionList.insert(row,regionF);
posF +=50;
}
int posS = x0+40;
SRegionList.clear();
for(row = 0;row<model()->rowCount(rootIndex());row++)
{
QModelIndex index =model()->index(row,3,rootIndex());
int male = 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-male*10,width,male*10));
QRegion regionS(posS,y0-male*10,width,male*10);
SRegionList.insert(row,regionS);
posS +=50;
}
}
void HistogramView::mousePressEvent(QMouseEvent *event)
{
QAbstractItemView::mousePressEvent(event);
setSelection(QRect(event->pos().x(),event->pos().y(),1,1),QItemSelectionModel::SelectCurrent);
}
QRegion HistogramView::itemRegion(QModelIndex index)
{
QRegion region;
if(index.column() == 1)
{
region = MRegionList[index.row()];
}else if(index.column() == 2)
{
region = FRegionList[index.row()];
}
else if(index.column() == 3)
{
region = SRegionList[index.row()];
}
return region;
}
void HistogramView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
{
viewport()->update();
}
void HistogramView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
QAbstractItemView::dataChanged(topLeft,bottomRight);
viewport()->update();
}
void HistogramView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags flags)
{
int rows = model()->rowCount(rootIndex());
int columns = model()->columnCount(rootIndex());
QModelIndex selectedIndex;
for(int row =0;row<rows;row++)
{
for(int column = 1;column< columns;column++)
{
QModelIndex index= model()->index(row,column,rootIndex());
QRegion region = itemRegion(index);
if(!region.intersected(rect).isEmpty())
{
selectedIndex =index;
}
}
}
if(selectedIndex.isValid())
{
selections->select(selectedIndex,flags);
}else
{
QModelIndex noIndex;
selections->select(noIndex,flags);
}
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
运行图