Printing to paper in Qt - c++

I am new to qt. I want to make a simple project that will print text from the printer.
whenever I am using
QPrinter printer;
QPrintDialog *dialog = new QPrintDialog(&printer, this);
dialog->setWindowTitle(tr("Print Document"));
if (editor->textCursor().hasSelection())
dialog->addEnabledOption(QAbstractPrintDialog::PrintSelection);
if (dialog->exec() != QDialog::Accepted)
return;
or this
QPrinter printer(QPrinter::HighResolution);
printer.setOutputFileName("print.ps");
QPainter painter;
painter.begin(&printer);
for (int page = 0; page < numberOfPages; ++page) {
// Use the painter to draw on the page.
if (page != lastPage)
printer.newPage();
}
painter.end();
I just copy pasted this to my mainwindow.cpp(and tried pasting it to main.cpp too),to check if it works. It does not.
I am getting several errors like these
mainwindow.obj:-1: error: LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual _thiscall QPrinter::~QPrinter(void)" (_imp_??1QPrinter##UAE#XZ) referenced in function "private: void __thiscall MainWindow::on_pushButton_clicked(void)" (?on_pushButton_clicked#MainWindow##AAEXXZ).
could someone tell me step by step, how to print to a printer?
I also checked a lot online, but did not get any relevant tutorial , or even an example.
so, PLEASE write it here instead of linking me to another page.

I did some quick research being kind of surprised by your comments. The QtPrintSupport did change, so use for Qt5 (Detailed Description):
In Pro file:
QT += core gui printsupport
In cpp file:
#include <QtPrintSupport>
For printing from your QTextEdit *editor use:
editor->document()->print(&printer);

Related

QT: DirectShowPlayerService::doSetUrlSource: Unresolved error code 0x8007007b ()

I am using Qt Version 5.14.1.
When I was trying to play a video(.mp3), the program stopped working
And given error is DirectShowPlayerService::doSetUrlSource: Unresolved error code 0x8007007b ()
AudioPlayer::AudioPlayer(QObject *parent)
: QObject(parent)
, m_backgroundMusic(NULL) //QMediaPlayer * m_backgroundMusic
{
QUrl backgroundMusicUrl = QUrl::fromLocalFile(":/music/8bitDungeonLevel.mp3");
if (QFile::exists(backgroundMusicUrl.toLocalFile()))
{
m_backgroundMusic = new QMediaPlayer(this);
QMediaPlaylist * backgroundMusicList = new QMediaPlaylist();
QMediaContent media(backgroundMusicUrl);
backgroundMusicList->addMedia(media);
backgroundMusicList->setCurrentIndex(0);
backgroundMusicList->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
m_backgroundMusic->setPlaylist(backgroundMusicList);
}
}
void AudioPlayer::startBGM()
{
if (m_backgroundMusic)
{
qDebug() << m_backgroundMusic;
m_backgroundMusic->play();
}
}
the output as below
QMediaPlayer(0x3987eb0)
DirectShowPlayerService::doSetUrlSource: Unresolved error code 0x8007007b ()
I search the Internet and add LAV Filters to QT installation directory
, I also restart the computer but nothing changes.So how to fix it?
Your path in QUrl::fromLocalFile(":/music/8bitDungeonLevel.mp3") appears to be off, AFIK there is no (at least not common) path naming scheme that uses : to begin paths.
UPDATE:
I was told that :/ refers to resources that have been compiled into a Qt application, I think using the Qt Resource Compiler (rcc)
Use this code to load mp3 from resources:
m_mediaPlayer.setMedia(QUrl("qrc:/Audio/MouseOver.mp3"));
(do no forget do delete fromLocalFile)

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.

Finding the length of a song

I want to find the length of a song in seconds so that I can make a playlist with the M3U format, but I don't know how to get that info from the file. I am using id3lib and also Qt.
I've tried:
ID3_Frame* myFrame = myTag.Find(ID3FID_SONGLEN);
ID3_Frame* myFrame = myTag.Find(ID3FID_TIME);
ID3_Frame* myFrame = myTag.Find(ID3FID_SIZE);
but myFrame was NULL. I tried other parameters and worked, like ID3FID_ALBUM. I really don't know what to try. I didn't find anything in the id3lib API.
I know that Qt can give me that info, but can't I use id3lib?
Later edit: I've read that MediaObject::totalTime() gives me the time only if the song is played but I want that info, regarding that the songs are played or not; I need this info to write it in a file.
LATER EDIT:
I am trying to use Phonon from Qt for the length, but i receive a lot of errors.
#include <Phonon/MediaSource>
#include <Phonon/MediaObject>
#include <iostream>
#include <Qstring>
/* stuff */
Phonon::MediaObject *mediaObject = new Phonon::MediaObject();
QString fileName("D:/melodie.mp3");
mediaObject->setCurrentSource(fileName);
cout << mediaObject->totalTime() << endl;
I get a lot of unresolved external symbol
main.obj:-1: error: LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall Phonon::MediaObject::MediaObject(class QObject *)" (_imp??0MediaObject#Phonon##QAE#PAVQObject###Z) referenced in function _main
I am using QCreator, my application is simple, just a window that says hello(it works if i don't use Phonon); i just can't make it run; i've allocated static mediaObject, i've made a MediaSource and tried to pass it, but it doesn't work(here it says that can't covert from MediaSource* to MediaSource &). What could be the problem?
You can use Phonon::MediaObject::totalTime() to get the length of the song in milliseconds.
id3lib does not provide a function to directly find the length of a song because track length is not part of the ID3v1 or ID3v2 "standards". They are merely for tagging. If you're getting a 0 when you try the code in your question, it probably means that those tags haven't been set yet. As noted in the docs, "...the Find() method will return a NULL pointer if no such frame can be found."
Use MediaObject::totalTime after setting correctly the media source
I suggest you to use totalTimeChanged(qint64 newTotalTime) signal. It is more careful way to capture length of the track, because you don't need to manually check state of mediaObject.

Will loading a DLL dynamically reconcile its stderr to a main application? If so, then how...?

I'm writing a GUI application, using Qt, which links to a third-party DLL that sometimes sends error messages to stderr. I'd like these error messages to be displayed in a window within my GUI.
I couldn't find an established way to redirect stderr (as opposed to std::cerr) even after much searching, so I wrote the following class myself:
class StdErrRedirect : public QObject
{
Q_OBJECT
public:
// Constructor
StdErrRedirect(QTextEdit *errorLog,
QObject *parent = NULL);
// Destructor
~StdErrRedirect();
private slots:
void fileChanged(const QString &filename);
private:
QFile tmp;
QFileSystemWatcher watcher;
QString tmpFileNameQtFormat;
QString tmpFileNameNativeFormat;
QTextEdit *m_errorLog;
QString oldContent;
};
StdErrRedirect::StdErrRedirect(QTextEdit *errorLog,
QObject *parent)
: QObject(parent)
{
// Store the pointer to the error log window
m_errorLog = errorLog;
// Create a temporary filename: first find the path:
tmpFileNameQtFormat = QDir::tempPath();
// Make sure the closing slash is present:
if (!tmpFileNameQtFormat.endsWith(QChar('/')))
tmpFileNameQtFormat.append(QChar('/'));
// Add the file name itself:
tmpFileNameQtFormat.append("nb_stderrlog");
// Obtain a version of the filename in the operating system's native format:
tmpFileNameNativeFormat = QDir::toNativeSeparators(tmpFileNameQtFormat);
// Set up redirection to this file:
freopen(tmpFileNameNativeFormat.toAscii().constData(), "a+", stderr);
// Initialise the QFileSystemWatcher:
connect(&watcher, SIGNAL(fileChanged(const QString &)),
this, SLOT(fileChanged(const QString &)));
watcher.addPath(tmpFileNameQtFormat);
tmp.setFileName(tmpFileNameQtFormat);
}
StdErrRedirect::~StdErrRedirect()
{
// Ensure the temporary file is properly deleted:
fclose(stderr);
tmp.close();
tmp.open(QIODevice::ReadWrite);
tmp.remove();
}
void StdErrRedirect::fileChanged(const QString &filename)
{
tmp.open(QIODevice::ReadOnly);
QTextStream stream(&tmp);
QString content = stream.readAll();
tmp.close();
// Identify what's new, and just send this to the window:
int newchars = content.size() - oldContent.size();
if (newchars)
{
m_errorLog -> append(content.right(newchars));
oldContent = content;
}
}
If I instantiate this from my main window using:
errorLog = new QTextEdit;
redirector = new StdErrRedirect(errorLog);
... then everything I write to stderr appears in the window.
So far, so good. The problem is that the DLL's output still does not. In a call to a DLL function which emits an error, if I put the code:
if (error != _OK)
{
error.PrintErrorTrace();
fprintf(stderr, "Should have printed an error \r\n");
fflush(stderr);
//fsync(_fileno(stderr)); Linux version
_commit(_fileno(stderr));
return;
}
...then the text "Should have printed an error" appears but the error message itself does not.
Now, I've read somewhere that this is probably because the redirection is being set up after the DLL was loaded at the beginning of the application, and so it's own stderr channel is unaffected. Therefore, I should be able to fix this by loading the DLL dynamically, after setting up the redirection, instead.
Here is my question, then: how do I do this? I can try putting the following code at the beginning of my application:
QLibrary extlib;
extlib.setFileName("libname");
extlib.setLoadHints(QLibrary::ResolveAllSymbolsHint);
extlib.load();
...but on its own it has no effect. I think this is because the linker is still setting the library up to be opened automatically. However, if I remove the DLL from the linker (I'm using VS2008, so I remove extlib.lib from the dependency list) then the application won't compile because the compiler can't find the symbols from the DLL.
So there's obviously something deeply wrong with what I'm trying to do here. Can anybody help?
Thanks,
Stephen.
Does the DLL really write to stderr? Or does it write to GetStdHandle(STD_ERROR_HANDLE) ? The first maps to the second, initially. But with freopen() you merely change the mapping. Anything written to STD_ERROR_HANDLE will still go there.
To redirect everyones error output, you would need SetStdHandle.
There is only one stderr, so my guess is that the problem is not that you need to load the dll dynamically, but somewhere in your redirection code. Your redirection code is written Linux style, where in windows things work differently.
if you could test your application on Linux, It would help to pin point the problem. If it works on Linux, that it is surly the redirection code.
Anyway, you should read some more about redirection and windows, as I don't think that what you are trying to do now will help you.

setCentralWidget() causing the QMainWindow to crash.. Why?

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
this->setupUi(this);
this->setupActions();
this->setWindowTitle(tr("CuteEdit"));
label = new QLabel(tr("No Open Files"));
this->setCentralWidget(label);
label->setAlignment(Qt::AlignCenter);
}
By above code, I get a GUI like this(Its a screenshot of whole screen, Only observe the window displayed in middle of page of ebook). (I used QT Designer)
Now, i want user to select File->Open.. A Dialog appears and file gets selected.. Its contents are to be displayed in *textEdit widget..
Function for that is below..
void MainWindow::loadFile()
{
QString filename = QFileDialog::getOpenFileName(this);
QFile file(filename);
if (file.open(QIODevice::ReadOnly|QIODevice::Text))
{
label->hide();
textEdit->setPlainText(file.readAll());
mFilePath = filename;
QMainWindow::statusBar()->showMessage(tr("File successfully loaded."), 3000);
}
}
The window crashes at line:-
textEdit->setPlainText(file.readAll());
But if i comment the line:-
this->setCentralWidget(label);
i mean i remove label as being the central widget, the program runs as expected.. Why?
And also, I am not clear about the concept of CentralWidget. Pls guide.
JimDaniel is right in his last edit. Take a look at the source code of setCentralWidget():
void QMainWindow::setCentralWidget(QWidget *widget)
{
Q_D(QMainWindow);
if (d->layout->centralWidget() && d->layout->centralWidget() != widget) {
d->layout->centralWidget()->hide();
d->layout->centralWidget()->deleteLater();
}
d->layout->setCentralWidget(widget);
}
Do you see that if your MainWindow already had centralWidget() Qt schedules this object for deletion by deleteLater()?
And centralWidget() is the root widget for all layouts and other widgets in QMainWindow. Not the widget which is centered on window. So each QMainWindow produced by master in Qt Creator already has this root widget. (Take a look at your ui_mainwindow.h as JimDaniel proposed and you will see).
And you schedule this root widget for deletion in your window constructor! Nonsense! =)
I think for you it's a good idea to start new year by reading some book on Qt. =)
Happy New Year!
Are you sure it's not label->hide() that's crashing the app? Perhaps Qt doesn't like you hiding the central widget. I use Qt but I don't mess with QMainWindow that often.
EDIT: I compiled your code. I can help you a bit. Not sure what the ultimate reason is as I don't use the form generator, but you probably shouldn't be resetting the central widget to your label, as it's also set by the designer, if you open the ui_mainwindow.h file and look in setupGui() you can see that it has a widget called centralWidget that's already set. Since you have used the designer for your GUI, I would use it all the way and put the label widget in there as well. That will likely fix your problems. Maybe someone else can be of more help...
I'm not sure I understood your problem, neither what the guys above said (which I guess are valid information) and it seems to be an old topic.
However, I think I had a problem that looks like this and solved it, so I want to contribute my solution in case it helps anyone.
I was trying to "reset" central widget using QLabels. I had three different ones, switch from first to second, then to third and failed to switch back to the first one.
This is my solution that worked:
Header file
QLabel *imageLabel;
Constructor
imageLabel = new QLabel("<img src='/folder/etc.jpg' />");
this->setCentralWidget(imageLabel);
Reset
imageLabel = NULL;
imageLabel = new QLabel("<img src='/folder/etc.jpg' />");
this->setCentralWidget(imageLabel);
Hope that helps
Aris