Detecting PDF Printing on Mac - c++

I use a QPrintDialog to initialize a QPrinter object like this:
QPrinter printer;
QPrintDialog dlg(&printer);
if (dlg.exec() == QDialog::Accepted)
{
/* Are we printing to PDF? */
}
On Windows, it's easy to detect if the output is going to a file or to a PDF writer. On a Mac, none of the same functions work:
if ((printer.outputFormat() == QPrinter::PdfFormat)
|| (!printer.outputFileName().isEmpty()))
{
qDebug("PDF mode");
}
Looking at a copy of qprintdialog_mac.mm online, in the function QPrintDialogPrivate::closeCarbonPrintPanel(), Qt attempts to detect if the output is redirected to a file. It stores the file name in a member of QMacPrintEnginePrivate. Somehow that name never makes its way to the QPrinter object. I'm not sure where the disconnect is.
So..... how can I tell if the print output is actually going to a file? I'm willing to get platform specific here if it's easy. I have zero Mac programming experience though.

This was a bug in Qt.
In Qt 5.3 the sample code provided will work because of the second condition, the call to QPrinter::outputFileName().

As of Qt 5.14, the outputFileName property of QPrinter is still null, even if "Save as PDF" was selected in the QPrintDialog.
However, when painting to the QPrinter object, the right thing is done.
if "Open with Preview" was selected, the painted contents will open
in preview.
if "Save as PDF" is selected, a file dialog will pop up
if "Send in Mail" is selected, the mail client will open with the PDF
attaced
etc.
Somehow, the QPrinter seems to store all the info from the dialog in an opaque way not accessible through public getters.
The correct way to support all the options from the mac print dialog seems to be:
QPrinter printer;
QPrintDialog dlg(&printer);
if (dlg.exec() == QDialog::Accepted)
{
QPainter painter;
painter.begin(&printer);
// do the painting
painter.end();
}
Unfortunately, it does not seem possible to extract the info out of the QPrinter object in case you like to implement your own printing logic.

Related

How can I know which printer is selected

I have a program with the typical printer dialog (made with QPrintDialog from Qt5.1) where you can select the printer you want from a list. Let's say you have printerA (selected by default), printerB, printerC and printerD. I have a problem with printerD so when the user selects it I want to do something (maybe show a popup message or maybe dissable some buttons).
I've been looking for how to know if printerD is selected but couldn't find it. I've search in QPrinter, QPrinterInfo, QPrintDialog and QDialog and I couldn't find it. Also I've found this here which I though it could help me but the answer only tells you how to set the default one.
If you don't know which dialog I am talking about, it's the same from here.
I also was thinking if this list may be a QListWidget Class but if it was that, i 'don't know how to get it.
So my question is: How may I know which is the printer selected in any moment of this PrinterDialog life? (While showing up).
Also, I want to add, that I tried to dissable the button for the printer which gives me error with the next code but the QList is empty so I can't reach the Print or Preferences Button to dissable it I don't know why:
QList<QPrinterInfo> info_list = QPrinterInfo::availablePrinters();
foreach(QPrinterInfo info, info_list)
{
if (info.state() == 3) // the printer gives error
{
QList<QPushButton *> allButtons = printDialog.findChildren<QPushButton *>();
for (int i = 0; i < allButtons.size(); i++)
{
if (allButtons.at(i)->text().contains("Print") || allButtons.at(i)->text().contains("Preferences"))
{
allButtons.at(i)->setDisabled(true);
}
}
}
}
Thank you in advance.
You are probably looking for the printer name: QPrinter::printerName.
QPrinter printer;
QPrintDialog printDialog(printer);
if (printDialog.exec() == QDialog::Accepted) {
// executed after the print dialog is closed and accepted.
if (printer.printerName() == "printerD") {
// show a message or do something special ...
}
// print ...
}
Note that QPrintDialog does not provide any method to check the selected printer while the printer dialog is still open (not yet accepted). Using undocumented hacks such as using findChildren will not work in a cross platform way as native print dialog may be used[1]:
On Windows and macOS, the native print dialog is used, which means
that some QWidget and QDialog properties set on the dialog won't be
respected. The native print dialog on macOS does not support setting
printer options, i.e. setOptions() and setOption() have no effect.
If you really want/need to determine printer selection in realtime, you should implement your own custom printer dialog.

Is it possible to remove "Write to PDF" from QPrinter dialog called from QPrintPreviewDialog?

I wan't to remove under Linux, "Write to PDF" from printers list in QPrinter settings dialog that is called, when printing document from QPrintPreviewDialog. Is it possible to do?
I've tried replacing print icon inside QPrintPreviewDialog with my own button and action, but still Qt shows standard QPrinter dialog, and I don't know how to remove "Write to PDF" from printers list in that dialog.
Short answer: no, there's no way to alter the printers list in the default print dialog.
Workaround: if the user choose that "Print to file" option, don't print anything (and maybe tell them they won't have a PDF from your app).
You can do it this way: connect the QPrintPreviewDialog::paintRequested signal to a slot like this:
void Widget::onPaintRequested(QPrinter *printer)
{
QVariant printername = printer->printEngine()->property(QPrintEngine::PPK_PrinterName);
if(printername.toString().isEmpty())
{
QMessageBox::information(this, "Print issue", "Print to file is not available for weird unknown reasons ...");
}
else
{
//supply the requested paint code
}
}
Some more (maybe inspiring) thoughts on the topic in the answer to this SO question.

Print a textEdit in Qt

How can I print the text available in a textEdit using Qt creator (C++)? Please help me with this. I created a note pad using a textEdit. Now I want to print the note pad content. That mean the text typed in textEdit. So please help me.
please mention header files that I need to include as well.
Here is something I tried previous. but it's not working. so please help me with this.
void MainWindow::on_action_Print_triggered()
{
QString textFromField = ui->txtEdit->toPlainText();
QPrinter printer(QPrinter::HighResolution);
printer.setOutputFileName("print.ps");
QPainter painter;
painter.begin(&printer);
printer.newPage();
painter.end();
}
QTextEdit already has method which allows you print it's content, so you don't need QPainter. Use this (I printed pdf as example):
QPrinter printer(QPrinter::HighResolution);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName("outputt.pdf");
ui->textEdit->print(&printer);
print()
And of course you need
#include <QPrinter>
but I think that it is already added in your project.

Qt QPrinter setPaperSize does not work properly

I am trying to create a Windows application (but will eventually port it to linux also, so cross-compatibility is important if possible) that will take a picture from a webcam and can print without using a printDialog box, but I am having an issue selecting a paper size. I would like the paper size to be set to 4" x 6" which is the A6 format, but when I use setPaperSize(QtPrinter::A6) it seems to default to the letter format. It does not always default to letter with all printers though, it looks like each printer handles the command differently, but most default to letter. I believe this may be an issue with Qt and printer compatibility with the drivers.
My question is: Does anyone know a way to set the printer to 4" by 6" in Qt that should work with all printers?
My code is shown below.
void MainWindow::Print() {
QPainter painter;
QPrinter *printer = new QPrinter(QPrinter::HighResolution);
printer->setPaperSize(QPrinter::A6);
if (!painter.begin(printer)) {
qWarning("Failed to open file");
return;
}
painter.fillRect(QRectF(QPointF(108,118),QPointF(110+352, 120+352)), Qt::black);
painter.fillRect(QRectF(QPointF(109,119),QPointF(109+352, 119+352)), Qt::white);
ui->graphicsView->scene()->render(&painter, QRectF(110,120, 350, 350), QRectF(0,0, ui->graphicsView->scene()->width(), ui->graphicsView->scene()->height()), Qt::IgnoreAspectRatio);
painter.drawText(110, 110, "Test");
painter.end();
}
I have tried the following for resizing the paper
printer->setPaperSize(QPrinter::A6)
printer->setPageSize(QPrinter::A6)
printer->setPaperSize(QSizeF(4.0, 6.0), QPrinter::Inch)
none of those seemed to work. If anyone could help me with this issue I would be very greateful
setPaperSize relies on information received from the printer driver, so to be really printer independant, calculare pageRects yourself.
See the pageRect and the paperRect property together with the fullPage property of QPrinter.
See also my answer to Printing pagerect issues where there is a (wrong) starting example of printing arbitrary print rects and how to fix the code given with the question.

Taking data from a Dialog in Qt and using it in a Ui

So I'm making a text editor using Qt and right now I have a button that opens a dialog called "Format text". I want it to work kind of like the dialog in notepad called "font" where you select a few text attributes from some drop down lists and it shows you what your text will look like. Right now I have it working where you can select the font style, font color, and font size and hit preview and it shows you in a box in the dialog what your text will look like. However, I have a button called "okay" which is supposed to change the highlighted text or the text you are about to type, but I can't figure out how to display those changes on the main window. The .ui files are private and a lot of the already made functions and pointers are the same in every ui file so if I change the ui file to pubic I have to change a whole bunch of things. Can anyway give me a simple answer? I'm trying to do this with as little confusion as possible. More coding and less confusion is better than less coding and more confusion for someone of my skill level. Sorry that this is all one giant paragraph and that I didn't provide any code, but I didn't think the code was necessary, however if you do need some of the code i'd be happy to share it.
Thank you for your help and your time. I hope you all have a nice evening.
QDialog have a signal called finished(), you can connect this signal with your slot. To accomplish your work, pass a QSettings or for simplicity QStringList to dialog settings (responsible for changing font, color ...), the QStringList will save user defined settings, after closing the dialog, iterate through QStringList member to alert Main window.
A pseudo code will look like this
Class Editor:
Editor::Editor()
{
TextSettings textSettings;
textSettings.setSettings(settings); // settings is a member
connect(textSettings, &finished(int)), this, SLOT(alertEditor(int)))
}
Editor::alertEditor(int s)
{
if(s == 0)
{
for (int i = 0; i < settings.size(); ++i)
settings.at(i).toLocal8Bit().constData(); // extract various user settings
}
}
Class TextSettings:
TextSettings::TextSettings(QStringList settings)
{
settings << ui->combobox->currentItem(); // font name as example
}