QPrinter runtime error - c++

EDIT: I managed to get a compiling and non crashing version. The only thing left is to get the desired output, however this particular question (why it crashes) has been answered so I am closing the question. I will post the working code before the broken one.
Good day! I am trying to create a small example that will simply create a pdf document. Everything compiles, however when the program starts it simply crashes. I am using Qt version 5.0.0
---New working code---
int main( int argc, char **argv )
{
QApplication app( argc, argv );
QTextDocument doc;
doc.setHtml( "<p>A QTextDocument can be used to present formatted text "
"in a nice way.</p>"
"<p align=center>It can be <b>formatted</b> "
"<font size=+2>in</font> <i>different</i> ways.</p>"
"<p>The text can be really long and contain many "
"paragraphs. It is properly wrapped and such...</p>" );
QPrinter printer;
printer.setOutputFileName("C:\\Users\\SameTime\\Desktop\\Cutie\\PDFPrintMaybe");
printer.setOutputFormat(QPrinter::PdfFormat);
doc.print(&printer);
printer.newPage();
return 0;
}
Here is the project code:
#-------------------------------------------------
#
# Project created by QtCreator 2013-06-08T10:07:11
#
#-------------------------------------------------
QT += core
QT -= gui
QT += printsupport
TARGET = PDFPrintMaybe
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
----Old code with error---
And here is the main cpp:
#include <QCoreApplication>
#include <QTextDocument>
#include <QPrinter>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTextDocument doc;
doc.setHtml("<h1>Testing, testing, is this thing on?!</h1>");
QPrinter printer;
printer.setOutputFileName("C:\\Users\\SameTime\\Desktop\\Cutie\\PDFPrintMaybe");
printer.setOutputFormat(QPrinter::PdfFormat);
doc.print(&printer);
printer.newPage();
return a.exec();
}
I am a bit at a loss since it is compiling but crashing (almost) instantly when ran.

Try to create the objects on the heap otherwise they get automatically deleted when they ran out of scope, then the framework probably tries to delete them again and crashes.
QTextDocument *doc = new QTextDocument();
doc->setHtml("<h1>Testing, testing, is this thing on?!</h1>");
QPrinter* printer = new QPrinter();
printer->setOutputFileName("C:\\Users\\SameTime\\Desktop\\Cutie\\PDFPrintMaybe");
printer->setOutputFormat(QPrinter::PdfFormat);
doc->print(printer);
printer->newPage();

Related

vc++ + QT translation of UI is not working

I have a project with QT in vc++ and I need to locate the string in the UI to different languages. I created a UI through the QTdesigner in the visual studio add in of visual studio 2012 and also I have installed the QT plugin to use the Qt features as well.
I have created a .pro file and added:
SOURCES += main.cpp
TRANSLATIONS += languagefileqt_es.ts
After I generate a linguist file SOURCES emminensmultiportqt_es.ts and it detected correctly all the strings in my IU. After that, I generate the .qm file using the release function of Qtlinguist.
My resources file is:
<RCC>
<qresource prefix="MyAppQT">
<file>languagefileqt_es.qm</file>
</qresource>
</RCC>
Then I have added this to my main.cpp:
QTranslator translator;
bool loaded = translator.load("languagefileqt_es");
qDebug() << "loaded " << loaded;
a.installTranslator(&translator);
And loaded returns true in all the cases. My problem is that the UI is not translated when the application is executed. It is weird because it has no effect.
Any clue about what I am missing or what could I check out?
Thanks a lot
Are you sure, that "languagefileqt_es" is the correct name of your language file? I would expect "languagefileqt_es.qm" instead.
Are you sure that you are loading from the correct directory? Unless you are loading from an internal compiled-in resource (:/languagefileqt_es.qm) you should refer to an absolute path to make sure, that you load the correct thing.
I discovered what was the problem. thanks #Jens for try to help.
I think I commit a mistake of not knowing how the translating mechanism was working. In my main.cpp I had:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindowQT w;
QTranslator translator;
bool loaded = translator.load("languagefileqt_es");
qDebug() << "loaded " << loaded;
a.installTranslator(&translator);
w.show();
return a.exec();
}
But I realized that if I execute
qDebug() << QApplication::translate("MainWindowQTClass", "...BOARDING", 0);
after the loading process it will return the string translated correctly. So I change the definition of my UI after the internationalization and it worked. Apparently, translation is done in a function called retranslateUi() which is called in the constructor.
The correct main.cpp should be:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTranslator translator;
bool loaded = translator.load("languagefileqt_es");
qDebug() << "loaded " << loaded;
a.installTranslator(&translator);
MainWindowQT w;
w.show();
return a.exec();
}

'search' was not declared in this scope

I am trying to learn C++, and I am using the Qt Framework. What I am currently trying to accomplish, is loading a custom font from the resource file. When I run this, File Found is output to the console window. When I uncomment the commented out line I get an error 'search' was not declared in this scope. In the Qt Creator I have objectName set to search. I assumed that I could then access it like how I wrote the commented out line, but I guess I can't. What am I doing wrong?
int main(int argc, char *argv[]){
QApplication a(argc, argv);
Apollo w;
w.show();
int fontID(-1);
QFile res(":/lib/fonts/SourceCodePro-ExtraLight.ttf");
if(res.open(QIODevice::ReadOnly) == true){
fontID = QFontDatabase::addApplicationFontFromData(res.readAll());
if(fontID == -1){
qDebug() << "File Not Found";
}else{
qDebug() << "File Found";
}
}
//search.setFont(QFont("Source Code Pro ExtraLight", 26));
return a.exec();
}
Your object names is "search".
The object is a part of the GUI I guess, so if you want to have acces to it you should do something like that:
ui->search->setFont(...);
Qt creator is quite smart and offer you a kind of auto complement. If it doesn't offer you a proposition for a object of the GUI most of the time that mean you do it wrong.

Qt create pdf example - can't get it to work

I looked at some examples and decided to implement one of them. It compiles and doesn't crash when ran, however It doesn't create the pdf, it throws some error (which I do not understand). The question is where there error is and how can it be removed?
The project code:
#-------------------------------------------------
#
# Project created by QtCreator 2013-06-08T10:07:11
#
#-------------------------------------------------
QT += core
QT -= gui
QT += printsupport
TARGET = PDFPrintMaybe
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
And the source itself:
#include <QTextDocument>
#include <QPrinter>
#include <QApplication>
int main( int argc, char **argv )
{
QApplication app( argc, argv );
QTextDocument doc;
doc.setHtml( "<p>A QTextDocument can be used to present formatted text "
"in a nice way.</p>"
"<p align=center>It can be <b>formatted</b> "
"<font size=+2>in</font> <i>different</i> ways.</p>"
"<p>The text can be really long and contain many "
"paragraphs. It is properly wrapped and such...</p>" );
QPrinter printer;
printer.setOutputFileName("C:\\Users\\SameTime\\Desktop");
printer.setOutputFormat(QPrinter::PdfFormat);
doc.print(&printer);
printer.newPage();
return 0;
}
And finally, the error itself:
QPainter:: begin(): Returned false
"C:\\Users\\SameTime\\Desktop"
probably refers to the existing folder, not a file name.
You should specify your pdf file name instead, like
"C:\\Users\\SameTime\\Desktop\\1.pdf"
And make sure that path to the file exists and accessible.
Otherwise, sustem would not be able to crate pdf and print (i.e. paint on the pdf canvas)

How to print pdf file in Qt

I have tried to write some code to print a pdf file using Qt but somehow it's not working.
If anybody has any idea to solve this problem, please provide your tips.
void ChartViewer::onprintBtnClicked(){
String filename = QFileDialog::getOpenFileName(this,"Open File",QString(),"Pdf File(*.pdf)");
qDebug()<<"Print file name is "<<filename;
if(!filename.isEmpty()) {
if(QFileInfo(filename).suffix().isEmpty())
filename.append(".pdf");
QPrinter printer(QPrinter::HighResolution);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName(filename);
QPrintDialog*dlg = new QPrintDialog(&printer,this);
if(textedit->textCursor().hasSelection())
dlg->addEnabledOption(QAbstractPrintDialog::PrintSelection);
dlg->setWindowTitle(tr("Print Document"));
if(dlg->exec() == QDialog::Accepted) {
textedit->print(&printer);
}
delete dlg;
}
}
I didn't understand your question, but now I get it. You want to print PDF file using Qt, you don't want to print into PDF, right?
Qt does not have support for loading and display PDF.
For PDF support in Qt you need external library poppler. Check this article.
Poppler allows you to render PDF files into QImage and you can easily print QImage
like this.
Here is how do you print text into PDF file.
I tried to edit your code so that I can test it a bit and it works for me, can you check?
Maybe try to check if QPrinter::isValid() returns true in your environment.
#include <QtGui>
#include <QtCore>
int main(int argc, char **argv) {
QApplication app(argc, argv);
QTextEdit parent;
parent.setText("We are the world!");
parent.show();
QString filename = QFileDialog::getOpenFileName(&parent,"Open File",QString(),"Pdf File(*.pdf)");
qDebug()<<"Print file name is "<<filename;
if(!filename.isEmpty()) {
if(QFileInfo(filename).suffix().isEmpty()) {
filename.append(".pdf");
}
QPrinter printer(QPrinter::HighResolution);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName(filename);
QPrintDialog*dlg = new QPrintDialog(&printer,&parent);
dlg->setWindowTitle(QObject::tr("Print Document"));
if(dlg->exec() == QDialog::Accepted) {
parent.print(&printer);
}
delete dlg;
}
return app.exec();
}

Console output in a Qt GUI app?

I have a Qt GUI application running on Windows that allows command-line options to be passed and under some circumstances I want to output a message to the console and then quit, for example:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
if (someCommandLineParam)
{
std::cout << "Hello, world!";
return 0;
}
MainWindow w;
w.show();
return a.exec();
}
However, the console messages do not appear when I run the app from a command-prompt. Does anyone know how I can get this to work?
Windows does not really support dual mode applications.
To see console output you need to create a console application
CONFIG += console
However, if you double click on the program to start the GUI mode version then you will get a console window appearing, which is probably not what you want. To prevent the console window appearing you have to create a GUI mode application in which case you get no output in the console.
One idea may be to create a second small application which is a console application and provides the output. This can call the second one to do the work.
Or you could put all the functionality in a DLL then create two versions of the .exe file which have very simple main functions which call into the DLL. One is for the GUI and one is for the console.
Add:
#ifdef _WIN32
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
}
#endif
at the top of main(). This will enable output to the console only if the program is started in a console, and won't pop up a console window in other situations. If you want to create a console window to display messages when you run the app outside a console you can change the condition to:
if (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole())
void Console()
{
AllocConsole();
FILE *pFileCon = NULL;
pFileCon = freopen("CONOUT$", "w", stdout);
COORD coordInfo;
coordInfo.X = 130;
coordInfo.Y = 9000;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coordInfo);
SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE),ENABLE_QUICK_EDIT_MODE| ENABLE_EXTENDED_FLAGS);
}
int main(int argc, char *argv[])
{
Console();
std::cout<<"start##";
qDebug()<<"start!";
You can't use std::cout as others have said,my way is perfect even for some code can't include "qdebug" !
So many answers to this topic. 0.0
So I tried it with Qt5.x from Win7 to Win10. It took me some hours to have a good working solution which doesn't produce any problems somewhere in the chain:
#include "mainwindow.h"
#include <QApplication>
#include <windows.h>
#include <stdio.h>
#include <iostream>
//
// Add to project file:
// CONFIG += console
//
int main( int argc, char *argv[] )
{
if( argc < 2 )
{
#if defined( Q_OS_WIN )
::ShowWindow( ::GetConsoleWindow(), SW_HIDE ); //hide console window
#endif
QApplication a( argc, argv );
MainWindow *w = new MainWindow;
w->show();
int e = a.exec();
delete w; //needed to execute deconstructor
exit( e ); //needed to exit the hidden console
return e;
}
else
{
QCoreApplication a( argc, argv );
std::string g;
std::cout << "Enter name: ";
std::cin >> g;
std::cout << "Name is: " << g << std::endl;
exit( 0 );
return a.exec();
}
}
I tried it also without the "CONFIG += console", but then you need to redirect the streams and create the console on your own:
#ifdef _WIN32
if (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole()){
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
freopen("CONIN$", "r", stdin);
}
#endif
BUT this only works if you start it through a debugger, otherwise all inputs are directed towards the system too. Means, if you type a name via std::cin the system tries to execute the name as a command. (very strange)
Two other warnings to this attempt would be, that you can't use ::FreeConsole() it won't close it and if you start it through a console the app won't close.
Last there is a Qt help section in QApplication to this topic. I tried the example there with an application and it doesn't work for the GUI, it stucked somewhere in an endless loop and the GUI won't be rendered or it simply crashes:
QCoreApplication* createApplication(int &argc, char *argv[])
{
for (int i = 1; i < argc; ++i)
if (!qstrcmp(argv[i], "-no-gui"))
return new QCoreApplication(argc, argv);
return new QApplication(argc, argv);
}
int main(int argc, char* argv[])
{
QScopedPointer<QCoreApplication> app(createApplication(argc, argv));
if (qobject_cast<QApplication *>(app.data())) {
// start GUI version...
} else {
// start non-GUI version...
}
return app->exec();
}
So if you are using Windows and Qt simply use the console option, hide the console if you need the GUI and close it via exit.
No way to output a message to console when using QT += gui.
fprintf(stderr, ...) also can't print output.
Use QMessageBox instead to show the message.
Oh you can Output a message when using QT += gui and CONFIG += console.
You need printf("foo bar") but cout << "foo bar" doesn't works
Something you may want to investigate, at least for windows, is the AllocConsole() function in the windows api. It calls GetStdHandle a few times to redirect stdout, stderr, etc. (A quick test shows this doesn't entirely do what we want it to do. You do get a console window opened alongside your other Qt stuff, but you can't output to it. Presumably, because the console window is open, there is some way to access it, get a handle to it, or access and manipulate it somehow. Here's the MSDN documentation for those interested in figuring this out:
AllocConsole():
http://msdn.microsoft.com/en-us/library/windows/desktop/ms681944%28v=vs.85%29.aspx
GetStdHandle(...):
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683231%28v=vs.85%29.aspx
(I'd add this as a comment, but the rules prevent me from doing so...)
I used this header below for my projects. Hope it helps.
#ifndef __DEBUG__H
#define __DEBUG__H
#include <QtGui>
static void myMessageOutput(bool debug, QtMsgType type, const QString & msg) {
if (!debug) return;
QDateTime dateTime = QDateTime::currentDateTime();
QString dateString = dateTime.toString("yyyy.MM.dd hh:mm:ss:zzz");
switch (type) {
case QtDebugMsg:
fprintf(stderr, "Debug: %s\n", msg.toAscii().data());
break;
case QtWarningMsg:
fprintf(stderr, "Warning: %s\n", msg.toAscii().data());
break;
case QtCriticalMsg:
fprintf(stderr, "Critical: %s\n", msg.toAscii().data());
break;
case QtFatalMsg:
fprintf(stderr, "Fatal: %s\n", msg.toAscii().data());
abort();
}
}
#endif
PS: you could add dateString to output if you want in future.
First of all, why would you need to output to console in a release mode build? Nobody will think to look there when there's a gui...
Second, qDebug is fancy :)
Third, you can try adding console to your .pro's CONFIG, it might work.
In your .pro add
CONFIG += console
It may have been an oversight of other answers, or perhaps it is a requirement of the user to indeed need console output, but the obvious answer to me is to create a secondary window that can be shown or hidden (with a checkbox or button) that shows all messages by appending lines of text to a text box widget and use that as a console?
The benefits of such a solution are:
A simple solution (providing all it displays is a simple log).
The ability to dock the 'console' widget onto the main application window. (In Qt, anyhow).
The ability to create many consoles (if more than 1 thread, etc).
A pretty easy change from local console output to sending log over network to a client.
Hope this gives you food for thought, although I am not in any way yet qualified to postulate on how you should do this, I can imagine it is something very achievable by any one of us with a little searching / reading!
Make sure Qt5Core.dll is in the same directory with your application executable.
I had a similar issue in Qt5 with a console application:
if I start the application from Qt Creator, the output text is visible,
if I open cmd.exe and start the same application there, no output is visible.
Very strange!
I solved it by copying Qt5Core.dll to the directory with the application executable.
Here is my tiny console application:
#include <QCoreApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
int x=343;
QString str("Hello World");
qDebug()<< str << x<<"lalalaa";
QTextStream out(stdout);
out << "aldfjals alsdfajs...";
}
I also played with this, discovering that redirecting output worked, but I never saw output to the console window, which is present for every windows application. This is my solution so far, until I find a Qt replacement for ShowWindow and GetConsoleWindow.
Run this from a command prompt without parameters - get the window. Run from command prompt with parameters (eg. cmd aaa bbb ccc) - you get the text output on the command prompt window - just as you would expect for any Windows console app.
Please excuse the lame example - it represents about 30 minutes of tinkering.
#include "mainwindow.h"
#include <QTextStream>
#include <QCoreApplication>
#include <QApplication>
#include <QWidget>
#include <windows.h>
QT_USE_NAMESPACE
int main(int argc, char *argv[])
{
if (argc > 1) {
// User has specified command-line arguments
QCoreApplication a(argc, argv);
QTextStream out(stdout);
int i;
ShowWindow (GetConsoleWindow(),SW_NORMAL);
for (i=1; i<argc; i++)
out << i << ':' << argv [i] << endl;
out << endl << "Hello, World" << endl;
out << "Application Directory Path:" << a.applicationDirPath() << endl;
out << "Application File Path:" << a.applicationFilePath() << endl;
MessageBox (0,(LPCWSTR)"Continue?",(LPCWSTR)"Silly Question",MB_YESNO);
return 0;
} else {
QApplication a(argc, argv);
MainWindow w;
w.setWindowTitle("Simple example");
w.show();
return a.exec();
}
}
After a rather long struggle with exactly the same problem I found that simply
CONFIG += console
really does the trick. It won't work until you explicitly tell QtCreator to execute qmake on the project (right click on project) AND change something inside the source file, then rebuild. Otherwise compilation is skipped and you still won't see the output on the command line.
Now my program works in both GUI and cmd line mode.
One solution is to run powershell and redirect the output to whatever stream you want.
Below is an example of running powershell from cmd.exe and redirecting my_exec.exe output to both the console and an output.txt file:
powershell ".\my_exec.exe | tee output.txt"
An example (from cmd.exe) which holds open stdout/stderr and doesn't require tee or a temporary file:
my_exec.exe > NUL 2>&1
Easy
Step1: Create new project. Go File->New File or Project --> Other Project -->Empty Project
Step2: Use the below code.
In .pro file
QT +=widgets
CONFIG += console
TARGET = minimal
SOURCES += \ main.cpp
Step3: Create main.cpp and copy the below code.
#include <QApplication>
#include <QtCore>
using namespace std;
QTextStream in(stdin);
QTextStream out(stdout);
int main(int argc, char *argv[]){
QApplication app(argc,argv);
qDebug() << "Please enter some text over here: " << endl;
out.flush();
QString input;
input = in.readLine();
out << "The input is " << input << endl;
return app.exec();
}
I created necessary objects in the code for your understanding.
Just Run It
If you want your program to get multiple inputs with some conditions. Then past the below code in Main.cpp
#include <QApplication>
#include <QtCore>
using namespace std;
QTextStream in(stdin);
QTextStream out(stdout);
int main(int argc, char *argv[]){
QApplication app(argc,argv);
qDebug() << "Please enter some text over here: " << endl;
out.flush();
QString input;
do{
input = in.readLine();
if(input.size()==6){
out << "The input is " << input << endl;
}
else
{
qDebug("Not the exact input man");
}
}while(!input.size()==0);
qDebug(" WE ARE AT THE END");
// endif
return app.exec();
} // end main
Hope it educates you.
Good day,
First of all you can try flushing the buffer
std::cout << "Hello, world!"<<std::endl;
For more Qt based logging you can try using qDebug.