目前问题是 滚动条设置不起作用,然后 只能显示第一页pdf
#include "pdfbrowser.h"
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <QGraphicsView>
#include <QDebug>
PDFBrowser::PDFBrowser(QWidget *parent)
: QWidget{parent}
{
setAttribute(Qt::WA_OpaquePaintEvent);
setAttribute(Qt::WA_StaticContents);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_scrollArea = new QScrollArea(this);
vScrollBar = new QScrollBar(Qt::Vertical);
hScrollBar = new QScrollBar(Qt::Horizontal);
vScrollBar->setVisible(true);
hScrollBar->setVisible(true);
m_scrollArea->setBackgroundRole(QPalette::Base);
m_scrollArea->setAlignment(Qt::AlignCenter);
m_scrollArea->setFrameShape(QFrame::Box);
m_scrollArea->setVerticalScrollBar(vScrollBar);
m_scrollArea->setHorizontalScrollBar(hScrollBar);
m_scrollArea->setWidgetResizable(true);
view = new QGraphicsView();
scene = new QGraphicsScene() ;
m_scrollAreaContentLayout = new QVBoxLayout;
scrollAreaContent = new QWidget(this);
scrollAreaContent->setLayout(m_scrollAreaContentLayout);
m_scrollArea->setWidget(scrollAreaContent);
QVBoxLayout* layout = new QVBoxLayout;
layout->addWidget(m_scrollArea);
label = new QLabel(this);
m_scrollAreaContentLayout->addWidget(view);
setLayout(layout);
connect(vScrollBar, &QScrollBar::valueChanged, this, &PDFBrowser::onScrollBarValueChanged);
connect(hScrollBar, &QScrollBar::valueChanged, this, &PDFBrowser::onScrollBarValueChanged);
document = nullptr;
qDebug()<<"到这里了";
}
PDFBrowser::~PDFBrowser(){
if(m_scrollArea!=nullptr)
delete m_scrollArea;
if(vScrollBar!=nullptr)
delete vScrollBar;
if(hScrollBar!=nullptr)
delete hScrollBar;
if(document!=nullptr)
delete document;
FPDF_DestroyLibrary();
}
void PDFBrowser::resizeEvent(QResizeEvent *event){
//在widget重新变更位置时改变scrollba
QWidget::resizeEvent(event);
this->m_scrollArea->resize(this->size());
redraw();
}
PDFDocument* PDFBrowser::loadPDF(const QString& fileName){
qDebug()<<"hi hi hi555";
FPDF_InitLibrary();
FPDF_DOCUMENT pdocument = FPDF_LoadDocument(fileName.toStdString().c_str(), nullptr);
if (pdocument) {
PDFDocument* document = new PDFDocument(pdocument);
document->loadAllPage();
this->document = document;
int totalHeight = document->getTotalHeightInPixel();
int maxWidth = document->getMaxWidthInPixel();
vScrollBar->setSingleStep(20);
vScrollBar->setPageStep(20);
hScrollBar->setSingleStep(20);
hScrollBar->setPageStep(20);
vScrollBar->setVisible(true);
hScrollBar->setVisible(true);
vScrollBar->setRange(0, totalHeight - m_scrollArea->height());
hScrollBar->setRange(0, maxWidth - m_scrollArea->width());
// vScrollBar->setRange(0, 1000);
// hScrollBar->setRange(0, 1000);
//vScrollBar->setValue(1);
qDebug()<<"vScrollBarmaximum loadPDF:"+QString::number(vScrollBar->maximum());
};
redraw();
qDebug()<<"vScrollBarmaximum loadPDF2:"+QString::number(vScrollBar->maximum());
return this->document;
}
void PDFBrowser::redraw(){
if (document == nullptr) {
return;
}
// QPixmap result(m_scrollArea->width(), m_scrollArea->height());
// QPainter painter(&result);
// 设置背景颜色
// painter.setBackground(Qt::darkGray);
// painter.setBrush(Qt::darkGray);
// 获取widget大小
int canvasWidth = m_scrollArea->width();
int canvasHeight = m_scrollArea->height();
// 填充矩形区域
//painter.drawRect(0, 0, canvasWidth, canvasHeight);
// painter.fillRect(0, 0, canvasWidth, canvasHeight, Qt::white);
// Get scrollbar position
int selection = vScrollBar->value();
int hSelection = hScrollBar->value();
qDebug()<<"selection:"+QString::number(selection);
qDebug()<<"hSelection:"+QString::number(hSelection);
// Get canvas size and calculate beginX
QSize canvasSize = m_scrollArea->size();
//居中
int beginX = 0;
if (canvasSize.width() > document->getMaxWidthInPixel()) {
beginX = (canvasSize.width() - document->getMaxWidthInPixel()) / 2;
}
// Draw PDF pages to QPixmap and show it on canvas
QList<QGraphicsPixmapItem*> items;
int pageAtY = selection;
PDFPage *page = document->getPageAtPixel(pageAtY);
//获取当前页是第几页
int index = page->getIndex();
//前几页的总长度
int temp = 0;
for(int i=0;i<index;i++){
temp+=document->getAllPage()[i].getPageSizeInPixel(document->getFPdf_DOCUMENT())[1];
}
// painter.setBrush(QColor(Qt::white));
// 绘制矩形并填充背景色
int x = -hSelection + beginX;
int y = 0;
int width = document->getMaxWidthInPixel();
int height = canvasHeight;
//painter.drawRect(x, y, width, height);
//painter.fillRect(x, y, width, height, painter.brush());
// 当前页应该在这个位置绘制
int maginY = temp - selection;
int paintedCount = 0;
int drawY = maginY;
PDFPage *currentPage = nullptr;
while (paintedCount <=3000) {
page = document->getPageAtPixel(pageAtY);
if(page==nullptr)
return;
qDebug()<<"pageIndex:"+QString::number(page->getIndex());
if (currentPage == page) {
break;
}
currentPage = page;
int pageWidth = currentPage->getPageSizeInPixel(this->document->getFPdf_DOCUMENT())[0];
int pageHeight = currentPage->getPageSizeInPixel(this->document->getFPdf_DOCUMENT())[1];
qDebug()<<"paintedCount:"+QString::number(paintedCount);
qDebug()<<"currentPage:"+ QString::number(currentPage->getIndex());
QGraphicsPixmapItem* item = new QGraphicsPixmapItem(currentPage->render(-hSelection + beginX, drawY, pageWidth, pageHeight, 0, 0));
item->setPos(-hSelection + beginX, drawY+1);
items.append(item);
// 已经绘制了这么多,离整个clientArea还有一段距离,不够的话接着取下一页
paintedCount += pageHeight + maginY;
// 下一页的坐标(滚动条偏移+当前页大小+偏移),多一个像素去寻找下一页
pageAtY = pageHeight + selection + maginY + 1;
// 下一页画的y坐标
drawY += pageHeight;
}
// int px = -hSelection + beginX;
// int py = maginY;
// 在绘图设备上绘制所有QPixmap
// foreach (const QPixmap& pixmap, list) {
// painter.drawPixmap(px, py, pixmap);
// int x1 = px;
//int y1 = pixmap.height() + py + 1;
//int x2 = pixmap.width() + px;
//int y2 = y1;
//painter.drawLine(x1, y1, x2, y2);
//py += pixmap.height() + 1; // 两个QPixmap之间加上10px的间距
//}
qDebug()<<"items:"+QString::number(items.size());
scene->clear();
int i = 0;
scene->addItem(items[1]);
foreach(QGraphicsPixmapItem* item, items) {
if(i==2)
continue;
i++;
qDebug()<<"item-x:"+QString::number(item->x())+" item-y"+QString::number(item->y());
// scene->addItem(item);
}
// 在绘图设备上绘制所有QGraphicsPixmapItem
qDebug()<<"scene:"+QString::number(scene->sceneRect().height());
view->setScene(scene);
//scene.render(&painter);
//label->setPixmap(result);
// painter.end();
}
#ifndef PDFBROWSER_H
#define PDFBROWSER_H
#include<QLabel>
#include<QScrollBar>
#include<QGridLayout>
#include "pdfdocument.h"
#include <QWidget>
#include <QPainter>
#include <QScrollArea>
#include <QString>
#include <QGraphicsView>
class PDFBrowser : public QWidget
{
public:
PDFBrowser(QWidget *parent);
~PDFBrowser();
PDFDocument* loadPDF(const QString& fileName);
public slots:
void onScrollBarValueChanged(){
qDebug()<<"vScrollBarmaximum:"+QString::number(vScrollBar->maximum());
qDebug()<<"m_scrollArea:"+QString::number(m_scrollArea->height());
qDebug()<<"scrollAreaContent:"+QString::number(scrollAreaContent->height());
qDebug()<<"vScrollBarvalue:"+QString::number(vScrollBar->value());
this->redraw();
}
protected:
void resizeEvent(QResizeEvent *event) override ;
private:
QScrollBar* vScrollBar = nullptr;
QScrollBar* hScrollBar = nullptr;
QScrollArea* m_scrollArea = nullptr;
QVBoxLayout* m_scrollAreaContentLayout;
PDFDocument* document;
QWidget *scrollAreaContent;
QLabel *label;
QGraphicsView* view;
QGraphicsScene* scene;
void redraw();
};
#endif // PDFBROWSER_H
#include "pdfpage.h"
#include "fpdfview.h"
#include <QApplication>
#include <QScreen>
PDFPage::PDFPage(int index) {
this->index = index;
}
int PDFPage::toPixel(int size) {
int dpi = QGuiApplication::primaryScreen()->physicalDotsPerInch();
return size * dpi / 72;
}
QList<int> PDFPage::getPageSize(const FPDF_DOCUMENT& document) {
if (this->wh.size() > 1)
return this->wh;
// 计算需要的图像大小(以像素为单位)
// int width = FPDF_GetPageWidth(page) * dpi / 72.0;
//int height = FPDF_GetPageHeight(page) * dpi / 72.0;
double pageWidth = 0.0;
double pageHeight = 0.0;
if (FPDF_GetPageSizeByIndex(document, index, &pageWidth, &pageHeight)) {
this->wh.append((int)pageWidth);
this->wh.append((int)pageHeight);
}
return this->wh;
}
QPixmap PDFPage::render(
int start_x,
int start_y,
int size_x,
int size_y,
int rotate,
int flags) {
FPDF_BITMAP bitmap = FPDFBitmap_Create(size_x, size_y, 1);
double x = 0;
double y = 0;
x = FPDF_GetPageWidthF(page);
y = FPDF_GetPageHeightF(page);
qDebug()<<"x:"+QString::number(x)+" y:"+QString::number(y)+" size_x:"+QString::number(size_x)+" size_y:"+QString::number(size_y);
FPDFBitmap_FillRect(bitmap, start_x, start_y, size_x, size_y, 0xFFFFFFFF);
FPDF_RenderPageBitmap(bitmap, page, start_x, start_y, size_x, size_y, 0, FPDF_ANNOT);
// 获取位图数据缓冲区的指针和行距信息
unsigned char* buffer = (unsigned char*)FPDFBitmap_GetBuffer(bitmap);
int stride = FPDFBitmap_GetStride(bitmap);
// 创建QImage对象
QImage image(buffer, size_x, size_y, stride, QImage::Format_ARGB32);
// 将QImage对象转换为QPixmap对象
QPixmap pixmap = QPixmap::fromImage(image);
FPDFBitmap_Destroy(bitmap);
return pixmap;
}
int PDFPage::getIndex() {
return this->index;
}
QList<int> PDFPage::getPageSizeInPixel(const FPDF_DOCUMENT& document) {
QList<int> pageSize = getPageSize(document);
QList<int> NewOne;
NewOne.append(toPixel(pageSize[0]));
NewOne.append(toPixel(pageSize[1]));
return NewOne;
}
float PDFPage::getWHRatio(const FPDF_DOCUMENT& document) {
QList<int> pageSize = getPageSize(document);
return (float)(pageSize[1] / pageSize[0]);
}
void PDFPage::close() const {
FPDF_ClosePage(this->page);
}