main.cpp 范例文件

itemmodel/main.cpp
/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Data Visualization module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:GPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 or (at your option) any later version ** approved by the KDE Free Qt Foundation. The licenses are as published by ** the Free Software Foundation and appearing in the file LICENSE.GPL3 ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/
#include <QtDataVisualization/q3dbars.h> #include <QtDataVisualization/qcategory3daxis.h> #include <QtDataVisualization/qitemmodelbardataproxy.h> #include <QtDataVisualization/qvalue3daxis.h> #include <QtDataVisualization/q3dscene.h> #include <QtDataVisualization/q3dcamera.h> #include <QtDataVisualization/qbar3dseries.h> #include <QtDataVisualization/q3dtheme.h> #include <QtWidgets/QApplication> #include <QtWidgets/QVBoxLayout> #include <QtWidgets/QTableWidget> #include <QtGui/QScreen> #include <QtCore/QRandomGenerator> #include <QtCore/QTimer> #include <QtGui/QFont> #include <QtCore/QDebug> #include <QtWidgets/QHeaderView> #include <QtWidgets/QMessageBox> #define USE_STATIC_DATA using namespace QtDataVisualization; class GraphDataGenerator : public QObject { public: explicit GraphDataGenerator(Q3DBars *bargraph, QTableWidget *tableWidget); ~GraphDataGenerator(); void setupModel(); void addRow(); void changeStyle(); void changePresetCamera(); void changeTheme(); void start(); void selectFromTable(const QPoint &selection); void selectedFromTable(int currentRow, int currentColumn, int previousRow, int previousColumn); void fixTableSize(); private: Q3DBars *m_graph; QTimer *m_dataTimer; int m_columnCount; int m_rowCount; QTableWidget *m_tableWidget; // not owned }; GraphDataGenerator::GraphDataGenerator(Q3DBars *bargraph, QTableWidget *tableWidget) : m_graph(bargraph), m_dataTimer(0), m_columnCount(100), m_rowCount(50), m_tableWidget(tableWidget) { // Set up bar specifications; make the bars as wide as they are deep, // and add a small space between them m_graph->setBarThickness(1.0f); m_graph->setBarSpacing(QSizeF(0.2, 0.2)); #ifndef USE_STATIC_DATA // Set up sample space; make it as deep as it's wide m_graph->rowAxis()->setRange(0, m_rowCount); m_graph->columnAxis()->setRange(0, m_columnCount); m_tableWidget->setColumnCount(m_columnCount); // Set selection mode to full m_graph->setSelectionMode(QAbstract3DGraph::SelectionItemRowAndColumn); // Hide axis labels by explicitly setting one empty string as label list m_graph->rowAxis()->setLabels(QStringList(QString())); m_graph->columnAxis()->setLabels(QStringList(QString())); m_graph->seriesList().at(0)->setItemLabelFormat(QStringLiteral("@valueLabel")); #else // Set selection mode to slice row m_graph->setSelectionMode(QAbstract3DGraph::SelectionItemAndRow | QAbstract3DGraph::SelectionSlice); #endif // Set theme m_graph->activeTheme()->setType(Q3DTheme::ThemeDigia); // Set font m_graph->activeTheme()->setFont(QFont("Impact", 20)); // Set preset camera position m_graph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetFront); } GraphDataGenerator::~GraphDataGenerator() { if (m_dataTimer) { m_dataTimer->stop(); delete m_dataTimer; } delete m_graph; } void GraphDataGenerator::start() { #ifndef USE_STATIC_DATA m_dataTimer = new QTimer(); m_dataTimer->setTimerType(Qt::CoarseTimer); QObject::connect(m_dataTimer, &QTimer::timeout, this, &GraphDataGenerator::addRow); m_dataTimer->start(0); m_tableWidget->setFixedWidth(m_graph->width()); #else setupModel(); // Table needs to be shown before the size of its headers can be accurately obtained, // so we postpone it a bit m_dataTimer = new QTimer(); m_dataTimer->setSingleShot(true); QObject::connect(m_dataTimer, &QTimer::timeout, this, &GraphDataGenerator::fixTableSize); m_dataTimer->start(0); #endif } void GraphDataGenerator::setupModel() { // Set up row and column names QStringList days; days << "Monday" << "Tuesday" << "Wednesday" << "Thursday" << "Friday" << "Saturday" << "Sunday"; QStringList weeks; weeks << "week 1" << "week 2" << "week 3" << "week 4" << "week 5"; // Set up data Mon Tue Wed Thu Fri Sat Sun float hours[5][7] = {{2.0f, 1.0f, 3.0f, 0.2f, 1.0f, 5.0f, 10.0f}, // week 1 {0.5f, 1.0f, 3.0f, 1.0f, 2.0f, 2.0f, 3.0f}, // week 2 {1.0f, 1.0f, 2.0f, 1.0f, 4.0f, 4.0f, 4.0f}, // week 3 {0.0f, 1.0f, 0.0f, 0.0f, 2.0f, 2.0f, 0.3f}, // week 4 {3.0f, 3.0f, 6.0f, 2.0f, 2.0f, 1.0f, 1.0f}}; // week 5 // Add labels m_graph->rowAxis()->setTitle("Week of year"); m_graph->rowAxis()->setTitleVisible(true); m_graph->columnAxis()->setTitle("Day of week"); m_graph->columnAxis()->setTitleVisible(true); m_graph->valueAxis()->setTitle("Hours spent on the Internet"); m_graph->valueAxis()->setTitleVisible(true); m_graph->valueAxis()->setLabelFormat("%.1f h"); m_tableWidget->setRowCount(5); m_tableWidget->setColumnCount(7); m_tableWidget->setHorizontalHeaderLabels(days); m_tableWidget->setVerticalHeaderLabels(weeks); m_tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); m_tableWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); m_tableWidget->setCurrentCell(-1, -1); m_tableWidget->setSelectionMode(QAbstractItemView::SingleSelection); for (int week = 0; week < weeks.size(); week++) { for (int day = 0; day < days.size(); day++) { QModelIndex index = m_tableWidget->model()->index(week, day); m_tableWidget->model()->setData(index, hours[week][day]); } } } void GraphDataGenerator::addRow() { m_tableWidget->model()->insertRow(0); if (m_tableWidget->model()->rowCount() > m_rowCount) m_tableWidget->model()->removeRow(m_rowCount); for (int i = 0; i < m_columnCount; i++) { QModelIndex index = m_tableWidget->model()->index(0, i); m_tableWidget->model()->setData(index, ((float)i / (float)m_columnCount) / 2.0f + (float)(QRandomGenerator::global()->bounded(30)) / 100.0f); } m_tableWidget->resizeColumnsToContents(); } void GraphDataGenerator::selectFromTable(const QPoint &selection) { m_tableWidget->setFocus(); m_tableWidget->setCurrentCell(selection.x(), selection.y()); } void GraphDataGenerator::selectedFromTable(int currentRow, int currentColumn, int previousRow, int previousColumn) { Q_UNUSED(previousRow) Q_UNUSED(previousColumn) m_graph->seriesList().at(0)->setSelectedBar(QPoint(currentRow, currentColumn)); } void GraphDataGenerator::fixTableSize() { int width = m_tableWidget->horizontalHeader()->length(); width += m_tableWidget->verticalHeader()->width(); m_tableWidget->setFixedWidth(width + 2); int height = m_tableWidget->verticalHeader()->length(); height += m_tableWidget->horizontalHeader()->height(); m_tableWidget->setFixedHeight(height + 2); } int main(int argc, char **argv) { QApplication app(argc, argv); Q3DBars *graph = new Q3DBars(); QWidget *container = QWidget::createWindowContainer(graph); if (!graph->hasContext()) { QMessageBox msgBox; msgBox.setText("Couldn't initialize the OpenGL context."); msgBox.exec(); return -1; } QSize screenSize = graph->screen()->size(); container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 2)); container->setMaximumSize(screenSize); container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); container->setFocusPolicy(Qt::StrongFocus); QWidget widget; QVBoxLayout *layout = new QVBoxLayout(&widget); QTableWidget *tableWidget = new QTableWidget(&widget); layout->addWidget(container, 1); layout->addWidget(tableWidget, 1, Qt::AlignHCenter); tableWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); tableWidget->setAlternatingRowColors(true); widget.setWindowTitle(QStringLiteral("Hours spent on the Internet")); // Since we are dealing with QTableWidget, the model will already have data sorted properly // into rows and columns, so we simply set useModelCategories property to true to utilize this. QItemModelBarDataProxy *proxy = new QItemModelBarDataProxy(tableWidget->model()); proxy->setUseModelCategories(true); QBar3DSeries *series = new QBar3DSeries(proxy); series->setMesh(QAbstract3DSeries::MeshPyramid); graph->addSeries(series); GraphDataGenerator generator(graph, tableWidget); QObject::connect(series, &QBar3DSeries::selectedBarChanged, &generator, &GraphDataGenerator::selectFromTable); QObject::connect(tableWidget, &QTableWidget::currentCellChanged, &generator, &GraphDataGenerator::selectedFromTable); widget.show(); generator.start(); return app.exec(); }