首页 > 解决方案 > 如果此系统没有任何打印机,如何在 Mac 上使用 QPageSetupDialog?

问题描述

我在 Mac 10.14.6 上使用 Qt 5.15.2

我尝试打开 QPageSetupDialog

QPrinter printer
QPageSetupDialog page(&printer);
page.exec();

但此对话框未打开并显示消息“QPageSetupDialog:无法在非本机打印机上使用”

我检查了源代码,发现如果 QPrinter 具有输出格式 NativeFormat,则打开 QPageSetupDialog,但我无法设置此格式,因为如果系统没有打印机,QPrinter 会忽略它。

我怎么解决这个问题?

标签: macosqt

解决方案


我在这里遇到了同样的问题。问题是,从 Qt5.6 开始,打印机的标准输出格式从 NativeFormat 更改为 PdfFormat。有几个相关的 QTBugs(例如 QTBUG-44940、QTBUG-57597)但没有有效的修复,至少对我来说是这样。

最后,我创建了自己的(简单)页面设置对话框。

头文件:simplepagesetupdialog.h

#ifndef SIMPLEPAGESETUPDIALOG_H
#define SIMPLEPAGESETUPDIALOG_H

#include <QDialog>
#include <QPrinter>
#include <QComboBox>
#include <QLineEdit>
#include <QRadioButton>

//-------------------------------------------------------------------------
class SimplePageSetupDialog : public QDialog
{
    Q_OBJECT

public:
    explicit SimplePageSetupDialog(QPrinter *pPrinter, QWidget *parent = 0);
    ~SimplePageSetupDialog();

private slots:
    void slot_pagesetup_accepted(void);

private:
    void createSimplePageSetupDialog(void);

    QPrinter *mpSetupPrinter;

    struct tSimplePageSetupDialog {
        QComboBox *paperSize;
        QRadioButton *orientationP;
        QRadioButton *orientationL;
        QLineEdit *marginLeft;
        QLineEdit *marginRight;
        QLineEdit *marginTop;
        QLineEdit *marginBottom;
    }GuiSimplePageSetupDialog;

    struct tSimplePageSetupDialog *uiPageSetup;
};

#endif // SIMPLEPAGESETUPDIALOG_H

源文件:simplepagesetupdialog.cpp

#include "simplepagesetupdialog.h"

#include <QGridLayout>
#include <QLabel>
#include <QGroupBox>
#include <QPushButton>
#include <QSpacerItem>
#include <QPrinterInfo>
#include <QPageSize>

#include <QDebug>


// This class is a workarround for QTBUG-44940, QTBUG-57597
// The problem is, that the QPageSetupDialog is not showing up on Mac OS 10.14

// Avoid redefinition of same connection between same elements
#define connect(src, sig, trgt, slt) connect(src, sig, trgt, slt, Qt::UniqueConnection)

///////////////////////////////////////////////////////////////////////////////////////////////////
// SimplePageSetupDialog class
///////////////////////////////////////////////////////////////////////////////////////////////////

/*-----------------------------------------------------------------------------------------------*
 * Dialog constructor
 *-----------------------------------------------------------------------------------------------*/
SimplePageSetupDialog::SimplePageSetupDialog(QPrinter *pPrinter, QWidget *parent) :
    QDialog(parent),
    mpSetupPrinter(pPrinter)
{
    createSimplePageSetupDialog();
}

/*-----------------------------------------------------------------------------------------------*
 * Dialog destructor
 *-----------------------------------------------------------------------------------------------*/
SimplePageSetupDialog::~SimplePageSetupDialog()
{
    //
}

/*-----------------------------------------------------------------------------------------------*
 * Create page setup dialog elements
 *-----------------------------------------------------------------------------------------------*/
void SimplePageSetupDialog::createSimplePageSetupDialog()
{
    bool bManualList = false;
    uiPageSetup = &GuiSimplePageSetupDialog;

    // Paper size ======================================================================
    // Create groupbox for paper size
    QHBoxLayout *pHBoxLayoutPaper = new QHBoxLayout();
    uiPageSetup->paperSize = new QComboBox();

    QPrinterInfo *pPrinterInfo = new QPrinterInfo(QPrinterInfo::defaultPrinter());
    QList<QPageSize> supportedPageSizes = pPrinterInfo->supportedPageSizes();
    if (supportedPageSizes.isEmpty()){
        //  Create manual pagesize list
        bManualList = true;
        for(int id = (int)QPageSize::A4; id < (int)QPageSize::LastPageSize; id++){
            QPageSize pz((QPageSize::PageSizeId)id);
            if (pz.isValid())
                supportedPageSizes.append(pz);
        }
    }

    int curPageSizeId = mpSetupPrinter->pageLayout().pageSize().id();
    int iIdxCnt = 0, iCurIdx = 0;
    foreach(QPageSize pz, supportedPageSizes)
    {
        if (bManualList == false)
            uiPageSetup->paperSize->addItem(pz.name());
        else
            uiPageSetup->paperSize->addItem(pz.name() + QString(" (%1 x %2 mm)")
                .arg(QString::number(pz.size(QPageSize::Millimeter).width()))
                .arg(QString::number(pz.size(QPageSize::Millimeter).height())));

        if (pz.id() == curPageSizeId)
            iCurIdx = iIdxCnt;
        iIdxCnt++;
    }
    uiPageSetup->paperSize->setCurrentIndex(iCurIdx);
    QLabel *pLabelPaperSize = new QLabel("Size:");
    pHBoxLayoutPaper->addWidget(pLabelPaperSize);
    pHBoxLayoutPaper->addWidget(uiPageSetup->paperSize);
    QGroupBox *pGroupboxPaper = new QGroupBox();
    pGroupboxPaper->setTitle("Paper");
    pGroupboxPaper->setLayout(pHBoxLayoutPaper);

    // Create groupbox for orientation
    QGridLayout* pGridLayoutOrientation = new QGridLayout();
    uiPageSetup->orientationP = new QRadioButton("Portrait");
    uiPageSetup->orientationP->setChecked(mpSetupPrinter->pageLayout().orientation() == QPageLayout::Portrait);
    uiPageSetup->orientationL = new QRadioButton("Landscape");
    uiPageSetup->orientationL->setChecked(mpSetupPrinter->pageLayout().orientation() == QPageLayout::Landscape);
    pGridLayoutOrientation->addWidget(uiPageSetup->orientationP,1,1);
    pGridLayoutOrientation->addWidget(uiPageSetup->orientationL,2,1);
    QGroupBox *pGroupboxOrientation = new QGroupBox();
    pGroupboxOrientation->setTitle("Orientation");
    pGroupboxOrientation->setLayout(pGridLayoutOrientation);

    // Create groupbox for Margins
    qreal left, top, right, bottom;
    int iUnit = mpSetupPrinter->pageLayout().units();
    mpSetupPrinter->getPageMargins(&left, &top, &right, &bottom, QPrinter::Millimeter);

    qDebug() << "unit " << iUnit;
    uint8_t iPrecision = 3;
    QGridLayout* pGridLayoutMargins = new QGridLayout();
    uiPageSetup->marginTop = new QLineEdit();
    uiPageSetup->marginTop->setFixedWidth(70);
    uiPageSetup->marginTop->setText(QString::number((mpSetupPrinter->pageLayout().margins().top()), 'f', iPrecision));
    uiPageSetup->marginLeft = new QLineEdit();
    uiPageSetup->marginLeft->setFixedWidth(70);
    uiPageSetup->marginLeft->setText(QString::number((mpSetupPrinter->pageLayout().margins().left()), 'f', iPrecision));
    uiPageSetup->marginRight = new QLineEdit();
    uiPageSetup->marginRight->setFixedWidth(70);
    uiPageSetup->marginRight->setText(QString::number((mpSetupPrinter->pageLayout().margins().right()), 'f', iPrecision));
    uiPageSetup->marginBottom = new QLineEdit();
    uiPageSetup->marginBottom->setFixedWidth(70);
    uiPageSetup->marginBottom->setText(QString::number((mpSetupPrinter->pageLayout().margins().bottom()), 'f', iPrecision));
    QLabel* pLabelMarginTop = new QLabel("Top:");
    QLabel* pLabelMarginLeft = new QLabel("Left:");
    QLabel* pLabelMarginRight = new QLabel("Right:");
    QLabel* pLabelMarginBottom = new QLabel("Bottom:");
    pGridLayoutMargins->addWidget(pLabelMarginLeft,1,1);
    pGridLayoutMargins->addWidget(uiPageSetup->marginLeft,1,2);
    pGridLayoutMargins->addWidget(pLabelMarginRight,1,3);
    pGridLayoutMargins->addWidget(uiPageSetup->marginRight,1,4);
    pGridLayoutMargins->addWidget(pLabelMarginTop,2,1);
    pGridLayoutMargins->addWidget(uiPageSetup->marginTop,2,2);
    pGridLayoutMargins->addWidget(pLabelMarginBottom,2,3);
    pGridLayoutMargins->addWidget(uiPageSetup->marginBottom,2,4);
    QGroupBox *pGroupboxMargins = new QGroupBox();
    pGroupboxMargins->setTitle(QString("Marings (mm)"));
    pGroupboxMargins->setLayout(pGridLayoutMargins);

    // Create pushbuttons
    QPushButton *pPushButtonOK = new QPushButton(QString("OK"));
    connect(pPushButtonOK, SIGNAL(clicked()), this, SLOT(slot_pagesetup_accepted()));
    connect(pPushButtonOK, SIGNAL(clicked()), this, SLOT(accept()));
    connect(pPushButtonOK, SIGNAL(clicked()), this, SLOT(deleteLater()));

    QPushButton *pPushButtonCancel = new QPushButton(QString("Cancel"));
    connect(pPushButtonCancel, SIGNAL(clicked()), this, SLOT(reject()));
    connect(pPushButtonCancel, SIGNAL(clicked()), this, SLOT(deleteLater()));

    QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);

    QHBoxLayout *pHBoxLayoutButtons = new QHBoxLayout();
    pHBoxLayoutButtons->addItem(spacer);
    pHBoxLayoutButtons->addWidget(pPushButtonOK);
    pHBoxLayoutButtons->addWidget(pPushButtonCancel);
    pHBoxLayoutButtons->setAlignment(Qt::AlignRight);
    pHBoxLayoutButtons->setSizeConstraint(pHBoxLayoutButtons->SetFixedSize);

    QGridLayout *pGridlayoutPageSetupDialog = new QGridLayout;
    pGridlayoutPageSetupDialog->addWidget(pGroupboxPaper, 1, 1, 1, 2);
    pGridlayoutPageSetupDialog->addWidget(pGroupboxOrientation, 2, 1);
    pGridlayoutPageSetupDialog->addWidget(pGroupboxMargins, 2, 2);


    // Create overlaying layout
    QVBoxLayout *pVBoxLayoutButtons = new QVBoxLayout();
    pVBoxLayoutButtons->addLayout(pGridlayoutPageSetupDialog);
    pVBoxLayoutButtons->addLayout(pHBoxLayoutButtons);
    pVBoxLayoutButtons->setSizeConstraint(pVBoxLayoutButtons->SetFixedSize);

    this->setLayout(pVBoxLayoutButtons);
    this->setWindowTitle(QString("Page Setup"));
}


/*-----------------------------------------------------------------------------------------------*
 * Page setup accepted
 *-----------------------------------------------------------------------------------------------*/
void SimplePageSetupDialog::slot_pagesetup_accepted()
{
    if (mpSetupPrinter != 0)
    {
        // Get paper size
        QPrinterInfo *pPrinterInfo = new QPrinterInfo(QPrinterInfo::defaultPrinter());
        QList<QPageSize> supportedPageSizes = pPrinterInfo->supportedPageSizes();

        if (supportedPageSizes.isEmpty()){
            for(int id = QPageSize::A4; id < QPageSize::LastPageSize; id++){
                QPageSize pz((QPageSize::PageSizeId)id);
                if (pz.isValid())
                    supportedPageSizes.append(pz);
            }
        }

        int curPageSizeId = uiPageSetup->paperSize->currentIndex();
        if ((curPageSizeId > -1) && (curPageSizeId < supportedPageSizes.length()))
        {
            mpSetupPrinter->setPageSize(supportedPageSizes.at(curPageSizeId));
        }

        // Get Orientation
        if (uiPageSetup->orientationP->isChecked())
            mpSetupPrinter->setOrientation(QPrinter::Portrait);
        else
            mpSetupPrinter->setOrientation(QPrinter::Landscape);

        // Get Margins
        qreal left, top, right, bottom;
        qreal newLeft, newTop, newRight, newBottom;
        mpSetupPrinter->getPageMargins(&left, &top, &right, &bottom, QPrinter::Millimeter);

        bool bOk;
        newTop = uiPageSetup->marginTop->text().toDouble(&bOk);
        if (!bOk || uiPageSetup->marginTop->text().isEmpty())
            newTop = top;
        newLeft = uiPageSetup->marginLeft->text().toDouble(&bOk);
        if (!bOk || uiPageSetup->marginLeft->text().isEmpty())
            newLeft = left;
        newRight = uiPageSetup->marginRight->text().toDouble(&bOk);
        if (!bOk || uiPageSetup->marginRight->text().isEmpty())
            newRight = right;
        newBottom = uiPageSetup->marginBottom->text().toDouble(&bOk);
        if (!bOk || uiPageSetup->marginBottom->text().isEmpty())
            newBottom = bottom;
        mpSetupPrinter->setFullPage(true); // Disable margin limitation checks
        mpSetupPrinter->setPageMargins(newLeft, newTop, newRight, newBottom, QPrinter::Millimeter);
    }
}

推荐阅读