Qt小例子学习60 - pdf 打印表格
connection.h
#ifndef CONNECTION_H
#define CONNECTION_H
#include <QMessageBox>
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
static bool createConnection()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(":memory:");
if (!db.open())
{
QMessageBox::critical(
nullptr, QObject::tr("Cannot open database"),
QObject::tr("Unable to establish a database connection.\n"
"This example needs SQLite support. Please read "
"the Qt SQL driver documentation for information how "
"to build it.\n\n"
"Click Cancel to exit."),
QMessageBox::Cancel);
return false;
}
QSqlQuery query;
query.exec("create table person (id int primary key, "
"firstname varchar(20), lastname varchar(20))");
query.exec("insert into person values(101, 'Danny', 'Young')");
query.exec("insert into person values(102, 'Christine', 'Holand')");
query.exec("insert into person values(103, 'Lars', 'Gordon')");
query.exec("insert into person values(104, 'Roberto', 'Robitaille')");
query.exec("insert into person values(105, 'Maria', 'Papadopoulos')");
query.exec("create table items (id int primary key,"
"imagefile int,"
"itemtype varchar(20),"
"description varchar(100))");
query.exec("insert into items "
"values(0, 0, 'Qt',"
"'Qt is a full development framework with tools designed to "
"streamline the creation of stunning applications and "
"amazing user interfaces for desktop, embedded and mobile "
"platforms.')");
query.exec("insert into items "
"values(1, 1, 'Qt Quick',"
"'Qt Quick is a collection of techniques designed to help "
"developers create intuitive, modern-looking, and fluid "
"user interfaces using a CSS & JavaScript like language.')");
query.exec("insert into items "
"values(2, 2, 'Qt Creator',"
"'Qt Creator is a powerful cross-platform integrated "
"development environment (IDE), including UI design tools "
"and on-device debugging.')");
query.exec("insert into items "
"values(3, 3, 'Qt Project',"
"'The Qt Project governs the open source development of Qt, "
"allowing anyone wanting to contribute to join the effort "
"through a meritocratic structure of approvers and "
"maintainers.')");
query.exec("create table images (itemid int, file varchar(20))");
query.exec("insert into images values(0, 'images/qt-logo.png')");
query.exec("insert into images values(1, 'images/qt-quick.png')");
query.exec("insert into images values(2, 'images/qt-creator.png')");
query.exec("insert into images values(3, 'images/qt-project.png')");
return true;
}
//! [0]
#endif
TransposeProxyModel.h
#ifndef TRANSPOSEPROXYMODEL_H
#define TRANSPOSEPROXYMODEL_H
#include <QAbstractProxyModel>
class TransposeProxyModel : public QAbstractProxyModel
{
public:
using QAbstractProxyModel::QAbstractProxyModel;
QModelIndex mapToSource(const QModelIndex &proxyIndex) const;
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const;
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &child) const;
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
};
#endif // TRANSPOSEPROXYMODEL_H
TransposeProxyModel.cpp
#include "transposeproxymodel.h"
QModelIndex
TransposeProxyModel::mapToSource(const QModelIndex &proxyIndex) const
{
if (sourceModel())
{
return sourceModel()->index(proxyIndex.column(), proxyIndex.row());
}
else
{
return QModelIndex();
}
}
QModelIndex
TransposeProxyModel::mapFromSource(const QModelIndex &sourceIndex) const
{
return index(sourceIndex.column(), sourceIndex.row());
}
QModelIndex TransposeProxyModel::index(int row, int column,
const QModelIndex &) const
{
return createIndex(row, column, (void *)0);
}
QModelIndex TransposeProxyModel::parent(const QModelIndex &) const
{
return QModelIndex();
}
int TransposeProxyModel::rowCount(const QModelIndex &) const
{
return sourceModel() ? sourceModel()->columnCount() : 0;
}
int TransposeProxyModel::columnCount(const QModelIndex &) const
{
return sourceModel() ? sourceModel()->rowCount() : 0;
}
QVariant TransposeProxyModel::headerData(int section,
Qt::Orientation orientation,
int role) const
{
if (!sourceModel())
{
return QVariant();
}
Qt::Orientation new_orientation =
orientation == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal;
return sourceModel()->headerData(section, new_orientation, role);
}
main.cpp
#include <QApplication>
#include <QPrintDialog>
#include <QPrinter>
#include <QPushButton>
#include <QSqlTableModel>
#include <QTableView>
#include <QTextDocument>
#include <QVBoxLayout>
#include "connection.h"
#include "transposeproxymodel.h"
#include <QDebug>
static void print_tableview(QTableView *view)
{
const QString format("<td>%1</td>");
QString html;
QAbstractItemModel *md = view->model();
html = "<html><body><table border=\"0\">";
html += "<td></td>";
for (int column = 0; column < md->columnCount(); column++)
{
QString data =
md->headerData(column, Qt::Horizontal, Qt::DisplayRole).toString();
html += format.arg(data);
}
for (int row = 0; row < md->rowCount(); row++)
{
html += "<tr>";
QString data =
md->headerData(row, Qt::Vertical, Qt::DisplayRole).toString();
html += format.arg(data);
for (int column = 0; column < md->columnCount(); column++)
{
QString data = md->index(row, column).data(Qt::DisplayRole).toString();
html += format.arg(data);
}
html += "</tr>";
}
html += "</table></body></html>";
QPrinter printer;
QPrintDialog *dialog = new QPrintDialog(&printer);
if (dialog->exec() == QDialog::Accepted)
{
QTextDocument document;
document.setHtml(html);
document.print(&printer);
}
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
if (!createConnection())
return -1;
QSqlTableModel model;
model.setTable("person");
model.select();
TransposeProxyModel proxy;
proxy.setSourceModel(&model);
QWidget w;
QVBoxLayout lay(&w);
QTableView view;
view.setModel(&proxy);
QPushButton btn("Print TableView");
QObject::connect(&btn, &QPushButton::clicked,
std::bind(print_tableview, &view));
lay.addWidget(&btn);
lay.addWidget(&view);
w.show();
return a.exec();
}