头发继续乱 2023-03-18 18:14 采纳率: 47.4%
浏览 66
已结题

设置滚动条范围没用,滚东条只能显示一页。


```c++
#include "pdfbrowser.h"
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <QDebug>
PDFBrowser::PDFBrowser(QWidget *parent)
    : QWidget{parent}
{

    setAttribute(Qt::WA_OpaquePaintEvent);
    setAttribute(Qt::WA_StaticContents);
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    vScrollBar = new QScrollBar(Qt::Vertical, this);
    hScrollBar = new QScrollBar(Qt::Horizontal, this);
    vScrollBar->setVisible(true);
    hScrollBar->setVisible(true);

    m_scrollArea = new QScrollArea(this);
    m_scrollArea->setBackgroundRole(QPalette::Base);
    m_scrollArea->setAlignment(Qt::AlignCenter);
    m_scrollArea->setFrameShape(QFrame::NoFrame);
    m_scrollArea->setVerticalScrollBar(vScrollBar);
    m_scrollArea->setHorizontalScrollBar(hScrollBar);
    m_scrollArea->setWidgetResizable(true);


    m_scrollAreaContentLayout  = new QVBoxLayout;
    scrollAreaContent = new QWidget;
    scrollAreaContent->setLayout(m_scrollAreaContentLayout);
    m_scrollArea->setWidget(scrollAreaContent);
    QVBoxLayout* layout = new QVBoxLayout;
    layout->addWidget(m_scrollArea);
    label = new QLabel(this);
    m_scrollAreaContentLayout->addWidget(label);
    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){

     this->m_scrollArea->resize(this->size());
    //在widget重新变更位置时改变scrollbar


    qDebug()<<"m_scrollArea->height():"+QString::number(m_scrollArea->height());
     qDebug()<<"m_scrollArea->width():"+QString::number(m_scrollArea->width());
      qDebug()<<"PDFBrowser->width():"+QString::number(this->width());
       qDebug()<<"PDFBrowser->height():"+QString::number(this->height());


   int totalHeight = document->getTotalHeightInPixel();
   int maxWidth = document->getMaxWidthInPixel();
   int vq =  totalHeight - m_scrollArea->height();
   int hq =  maxWidth - m_scrollArea->width();

    qDebug()<<"vq:"+QString::number(vq);
     qDebug()<<"hq:"+QString::number(hq);
   qDebug()<<"maxWidth:"+QString::number(maxWidth);
   qDebug()<<"totalHeight:"+QString::number(totalHeight);

    vScrollBar->setRange(0, totalHeight - m_scrollArea->height());
    hScrollBar->setRange(0, maxWidth - m_scrollArea->width());


    vScrollBar->setSingleStep(20);
    vScrollBar->setPageStep(20);
    hScrollBar->setSingleStep(20);
     hScrollBar->setPageStep(20);

     vScrollBar->setVisible(true);
      hScrollBar->setVisible(true);
    QWidget::resizeEvent(event);
     redraw();
     qDebug()<<" resizeEvent vScrollBar:"+QString::number(vScrollBar->maximum());
         qDebug()<<" resizeEvent  m_scrollArea:"+QString::number(m_scrollArea->height());

}

PDFDocument* PDFBrowser::loadPDF(const QString& fileName){
    qDebug()<<"hi hi hi555";
    FPDF_InitLibrary();

    FPDF_DOCUMENT pdocument = FPDF_LoadDocument(fileName.toStdString().c_str(), nullptr);
     qDebug()<<"hi hi hi556";
    if (pdocument) {
        PDFDocument* document = new PDFDocument(pdocument);
         qDebug()<<"hi hi hi551";
        document->loadAllPage();
        this->document = document;
        int totalHeight = document->getTotalHeightInPixel();
        int maxWidth = document->getMaxWidthInPixel();

        m_scrollArea->setMaximumWidth(maxWidth - m_scrollArea->width());
        m_scrollArea->setMaximumHeight(totalHeight - m_scrollArea->height());

        vScrollBar->setRange(0, totalHeight - m_scrollArea->height());
        hScrollBar->setRange(0, maxWidth - m_scrollArea->width());
    };
     redraw();
     qDebug()<<" load vScrollBar:"+QString::number(vScrollBar->maximum());
         qDebug()<<" load  m_scrollArea:"+QString::number(m_scrollArea->height());
    return  this->document;
}


void PDFBrowser::redraw(){


    int totalHeight = document->getTotalHeightInPixel();
    int maxWidth = document->getMaxWidthInPixel();

   // m_scrollArea->setMaximumWidth(maxWidth - m_scrollArea->width());
   // m_scrollArea->setMaximumHeight(totalHeight - m_scrollArea->height());


            qDebug()<<"vScrollBar:"+QString::number(vScrollBar->maximum());
                qDebug()<<"m_scrollArea:"+QString::number(m_scrollArea->height());

            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

            QGraphicsScene scene;
            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 <=canvasHeight) {
              qDebug()<<"drawY:"+QString::number(drawY);
                if(page==nullptr)
                    return;
                if (currentPage == page) {
                    break;
                }
                currentPage = page;
                int pageWidth = currentPage->getPageSizeInPixel(this->document->getFPdf_DOCUMENT())[0];
                int pageHeight = currentPage->getPageSizeInPixel(this->document->getFPdf_DOCUMENT())[1];



                QGraphicsPixmapItem* item = new QGraphicsPixmapItem(currentPage->render(-hSelection + beginX, drawY, pageWidth, pageHeight, 0, 0));
                item->setPos(-hSelection + beginX, drawY);
                items.append(item);
                pageAtY += currentPage->getPageSizeInPixel(this->document->getFPdf_DOCUMENT())[1];
                 page = document->getPageAtPixel(pageAtY);

                // 已经绘制了这么多,离整个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的间距
            //}

            foreach(QGraphicsPixmapItem* item, items) {
                   scene.addItem(item);
            }
            // 在绘图设备上绘制所有QGraphicsPixmapItem
            scene.render(&painter);

            label->setPixmap(result);


            painter.end();


}





#include <QApplication>
#include <QWidget>
#include <QScreen>

class CenteredWidget : public QWidget {
public:
    CenteredWidget(QWidget* parent = nullptr)
        : QWidget(parent) {
        setFixedSize(870, 770);
        const QRect screenRect = QGuiApplication::primaryScreen()->availableGeometry();
        move((screenRect.width() - width()) / 2,
             (screenRect.height() - height()) / 2);
    }
};


#include <QImage>
#include "fpdfview.h"
#include "fpdf_save.h"

// 渲染 PDF 页面到 QImage 中
QImage renderPageToQImage(FPDF_PAGE page, int dpi)
{
    // 计算需要的图像大小(以像素为单位)
    int width = FPDF_GetPageWidth(page) * dpi / 72.0;
    int height = FPDF_GetPageHeight(page) * dpi / 72.0;

    // 创建内存设备并将渲染结果保存到其中
    QImage image(width, height, QImage::Format_RGBA8888);
    FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(width, height, FPDFBitmap_BGR, image.bits(), (int)image.bytesPerLine());
    FPDF_RenderPageBitmap(bitmap, page, 0, 0, width, height, 0, FPDF_ANNOT);

    // 销毁位图对象
    FPDFBitmap_Destroy(bitmap);

    return image;
}
QImage pdfToQImage(const QString& filePath, int pageIndex, int dpi);
QImage renderPageToQImage(FPDF_PAGE page, int dpi);
// 将 PDF 文件转换为 QImage
QImage pdfToQImage(const QString& filePath, int pageIndex, int dpi)
{
    // 打开 PDF 文件
    QByteArray byteArray = filePath.toUtf8();
    const char* fileName = byteArray.constData();
    FPDF_DOCUMENT document = FPDF_LoadDocument(fileName, nullptr);
    if (!document) {
        qDebug() << "Failed to load document.";
        return QImage();
    }

    // 获取页面数量并打开指定页码的页面
    int pageCount = FPDF_GetPageCount(document);
    if (pageIndex >= pageCount) {
        qDebug() << "Invalid page index.";
        FPDF_CloseDocument(document);
        return QImage();
    }
    FPDF_PAGE page = FPDF_LoadPage(document, pageIndex);
    if (!page) {
        qDebug() << "Failed to load page.";
        FPDF_CloseDocument(document);
        return QImage();
    }

    // 设置 DPI 并渲染页面到 QImage 中
    QImage image = renderPageToQImage(page, dpi);

    // 关闭页面并销毁文档对象
    FPDF_ClosePage(page);
    FPDF_CloseDocument(document);

    return image;
}


#include <QApplication>
#include <QApplication>
#include <QFileDialog>
#include <QWidget>
#include <QVBoxLayout>
#include <QLabel>
#include <QDebug>
#include <QPushButton>
#include  "pdfbrowser.h"
// Include PDFium headers

#include "fpdfview.h"
int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
      CenteredWidget window;

       window.setWindowTitle("PDF Browser");

       PDFBrowser* pdfBrowser = new PDFBrowser(&window);
       pdfBrowser->resize(window.size());
     //  pdfBrowser->loadPDF("D:\\pdfD\\040300122068.pdf");
        pdfBrowser->loadPDF("D:\\pdfD\\2.pdf");
       pdfBrowser->setFixedSize(window.size());
       QVBoxLayout* layout = new QVBoxLayout;
       layout->addWidget(pdfBrowser);


       qDebug()<<"window的长:"+QString::number(window.height());
       qDebug()<<"window的款:"+QString::number(window.width());
       window.setLayout(layout);
       window.show();;
    return a.exec();
}


```

  • 写回答

5条回答 默认 最新

  • lshen01 2023-03-18 18:18
    关注

    参考GPT和自己的思路:

    根据代码,我发现在resizeEvent中对滚动条范围的设置被注释掉了,需要将以下两行代码的注释去掉:

    vScrollBar->setRange(0, totalHeight - m_scrollArea->height());
    hScrollBar->setRange(0, maxWidth - m_scrollArea->width());
    

    这样才能实现滚动条的正确工作,即可以滚动整个文档而不只是一页。同时,也可以在loadPDF函数中设置滚动条范围。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 3月19日
  • 修改了问题 3月18日
  • 创建了问题 3月18日

悬赏问题

  • ¥50 C# 使用DEVMOD设置打印机首选项
  • ¥15 麒麟V10 arm安装gdal
  • ¥15 想用@vueuse 把项目动态改成深色主题,localStorge里面的vueuse-color-scheme一开始就给我改成了dark,不知道什么原因(相关搜索:背景颜色)
  • ¥20 OPENVPN连接问题
  • ¥15 flask实现搜索框访问数据库
  • ¥15 mrk3399刷完安卓11后投屏调试只能显示一个设备
  • ¥100 如何用js写一个游戏云存档
  • ¥15 ansys fluent计算闪退
  • ¥15 有关wireshark抓包的问题
  • ¥15 需要写计算过程,不要写代码,求解答,数据都在图上