Qt程序设计(五):仪器管理软件-保存与浏览PDF

在博主设计的一个仪器管理软件中,搭建了示波器、频谱仪、DDS等仪器的软件界面,遇到了一个需求:设计希望能够将仪器测试结果以PDF格式保存下来,并且能够打开PDF浏览,实现更好的人机交互。本文将介绍这个功能的实现。

保存PDF

  图形绘制采用的是“Qt程序设计(四):气象自动监测站-数据实时曲线绘制https://blog.csdn.net/FPGADesigner/article/details/74315805 ”中用到的第三方类QCustomPlot,其给出了一个插入图片到QTextEdit控件,并保存为PDF的参考示例。
  
为了引用这个示例,把其封装好的相关文件qcpdocumentobject.h和qcpdocumentobject.cpp加入到自己的设计工程中(下载好QCustomPlot后可以找到这两个文件)。这个类提供了一个方法generatePlotFormat可以获取QCustomPlot对象的图形数据。

主程序中使用该方法插入图片到QTextEdit中:

//插入图片
void AutomaticStation::on_insertpicture_clicked()
{
    QTextCursor cursor = ui->textEdit->textCursor();

    double width = ui->sbwidth->value();
    double height = ui->sbheigh->value();

    if (ui->tabWidget->currentIndex() == 0)
    cursor.insertText(QString(QChar::ObjectReplacementCharacter), QCPDocumentObject::generatePlotFormat(ui->osci_plot, width, height));
    else if (ui->tabWidget->currentIndex() == 1)
    cursor.insertText(QString(QChar::ObjectReplacementCharacter), QCPDocumentObject::generatePlotFormat(ui->fft_plot, width, height));
    else if (ui->tabWidget->currentIndex() == 2)
    cursor.insertText(QString(QChar::ObjectReplacementCharacter), QCPDocumentObject::generatePlotFormat(ui->dds_plot, width, height));

    ui->textEdit->setTextCursor(cursor);
}

这是一个点击“插入图片”按钮的槽函数。程序中先获取光标在textEdit中的位置,获取图片的高度height和宽度width值,再根据Tab标签选择的界面,把不同QCustomPlot对象(osci_plot、fft_plot、dds_plot)以指定大小插入到光标所在位置。界面设计和实现效果如下图:
这里写图片描述
再设计点击“保存文档”按钮时的槽函数:

//保存pdf
void AutomaticStation::on_savepdf_clicked()
{
    QString fileName = QFileDialog::getSaveFileName(this, "Save document...", qApp->applicationDirPath(), "*.pdf");
    if (!fileName.isEmpty())
    {
      QPrinter printer;
      printer.setFullPage(true);
      printer.setPaperSize(QPrinter::A4);
      printer.setOrientation(QPrinter::Portrait);
      printer.setOutputFormat(QPrinter::PdfFormat);
      printer.setOutputFileName(fileName);
      ui->textEdit->document()->print(&printer);
    }
}

点击保存文档后,QFileDialog会弹出Windows的文件对话窗,填好文件名后,就会调用Qt的QPrinter类将textEdit中的内容按指定格式输出到PDF文件。

浏览PDF

保存PDF很简单,但解析PDF文件就比较困难了,网上也可以下载到一些解析PDF的第三方类,但使用起来还是比较繁琐。本设计为了追求简单高效,决定使用Qt提供的QAxWidget类,调用第三方ActiveX控件来打开PDF。
这里写图片描述
注意虽然ActiveX控件很多,但要搞清楚这个控件支不支持打开PDF。比如安装好福昕这个PDF阅读软件后,会有一个“FoxitReaderPlus Control”的控件,但博主在使用后发现无法打开PDF(显示为空白),怀疑是因为该控件不支持这个功能。后来改用Adobe Reader提供的“Adobe PDF Reader”控件后,打开成功。

新建一个窗口来显示PDF。设置一个“打开文件”的按钮,编写触发时的槽函数:

//点击“打开文件”按钮
void AutomaticStation::on_actionopenfile_triggered()
{
    QFileDialog dialog;

    dialog.setFileMode(QFileDialog::ExistingFile);
    dialog.setViewMode(QFileDialog::Detail);
    dialog.setOption(QFileDialog::ReadOnly, true);
    dialog.setDirectory(QString("./"));
    dialog.setNameFilter(QString("pdf(*.pdf)"));
    if (dialog.exec())
    {
        //根据文件后缀打开
        QStringList files = dialog.selectedFiles();
        for(auto filename : files)
        {
            if(filename.endsWith(".pdf"))
            {
                pdffilename = filename;
                this->openpdf();
            }
        }
     }
}

在对话框中选择PDF文件后,需要将PDF的文件名传递到显示窗口对应的类中,方法有很多,我这里用的是全局变量的方法。声明全局变量“QString pdffilename;”;显示窗口类中声明“extern QString pdffilename;”。

上面openpdf方法仅仅时打开显示PDF窗口,代码如下:

void AutomaticStation::openpdf(QString &filename)
{
    pdfshow *w2 = new pdfshow;
    w2->show();
}

显示窗口对应的类为pdfshow,在构造函数中调用ActiveX控件打开PDF:

pdfshow::pdfshow(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::pdfshow)
{
    ui->setupUi(this);

    //隐藏对话框的?按钮
    setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);


    pdfWidget = new QAxWidget(this);
    if(!pdfWidget->setControl("Adobe PDF Reader"))
        QMessageBox::critical(this, "Error", "open soft failed");

    ui->gridLayout->addWidget(pdfWidget);
    pdfWidget->dynamicCall("LoadFile(const QString&)", pdffilename);
}

我看到网上一些人在设置控件setControl时用的是COM对象,是一串很长的字符,搞得很多人都到处问怎样获得这个COM对象。其实只要你的系统中装了对应的程序和控件,输入控件名称就可以了。

另外还要在工程文件pro中声明QT += axcontainer。实际效果如下所示:
这里写图片描述
其实本质上就是通过ActiveX控件调用Adobe Reader程序来打开PDF文件。

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值