Receipt printer feeds paper instead of printing text - qt

I am working on test application for printing in Ubuntu 14.04.3 LTS with CUPS 1.7.2 and Qt 5.5.1 Opensource 64bit. I've added printer with its driver in CUPS and test page is printed ok. Now, my app consists of QTextEdit and QPushButton, whose pressed() signal triggers following slot:
void UeCentralWidget::ueSendTextToPrinter()
{
// QStringList availablePrintersNames=QPrinterInfo::availablePrinterNames();
// for(int indexPrinterName=0; indexPrinterName<availablePrintersNames.size(); indexPrinterName++)
// {
// qDebug() << Q_FUNC_INFO
// << availablePrintersNames.at(indexPrinterName);
// } // for
qDebug() << Q_FUNC_INFO
<< "Text to print: "
<< this->uePrinterTextEditor()->document()->toPlainText();
QList<QPrinterInfo> availablePrinters=QPrinterInfo::availablePrinters();
for(int indexPrinter=0; indexPrinter<availablePrinters.size(); indexPrinter++)
{
// qDebug() << Q_FUNC_INFO
// << availablePrinters.at(indexPrinter).makeAndModel();
if(availablePrinters.at(indexPrinter).makeAndModel().contains("POS58"))
{
qDebug() << Q_FUNC_INFO
<< "Printer found";
QPrinter printer(availablePrinters.at(indexPrinter));
qDebug() << Q_FUNC_INFO
<< printer.pageLayout().fullRect();
QPainter printerPainter(&printer);
qDebug() << Q_FUNC_INFO
<< printerPainter.fontInfo().family()
<< printerPainter.fontInfo().pixelSize()
<< printerPainter.fontInfo().pointSize();
if(printerPainter.begin(&printer))
{
printerPainter.drawText(100,
100,
this->uePrinterTextEditor()->document()->toPlainText());
}
printerPainter.end();
} // if
} // for
}
When this slot executes, printer job is added to CUPS queue, which means printer is found, however, printer just feeds printer and no text is printed. What am I still missing?

You don't need the printerPainter.begin(&printer) or the printerPainter.end().
I don't know why that fixes it for you, but if I was to guess it might be because explicitly calling printerPainter.end() prematurely completes the paint operation before the drawing is actually done.

Related

How can I make my waitForBytesWritten call non blocking ?

I have this function :
bool TCPClient::sendPacket(Protocol::Packet &packet)
{
if(this->tcpSocket->state() == QAbstractSocket::ConnectedState)
{
std::cout << "writing ..." << std::endl;
std::cout << sizeof(BabelPacket) + packet.dataLength << std::endl;
this->tcpSocket->write((const char *)&packet, sizeof(Protocol::BabelPacket) + packet.dataLength);
return this->tcpSocket->waitForBytesWritten(-1);
}
else
{
std::cout << "socket close" << std::endl;
return false;
}
}
But when I called it, it blocks my GUI.
Have you got an idea how I can make this call non blocking, and still have the readyRead signal triggered ?
Thanks

QAbstractVideoSurface generating A Null Image

I'm reimplemented the present method from a QAbstractVideo Surface in order to capture frames from an IP camera.
This is my reimplemented methods (the required ones):
QList<QVideoFrame::PixelFormat> CameraFrameGrabber::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const
{
Q_UNUSED(handleType);
return QList<QVideoFrame::PixelFormat>()
<< QVideoFrame::Format_ARGB32
<< QVideoFrame::Format_ARGB32_Premultiplied
<< QVideoFrame::Format_RGB32
<< QVideoFrame::Format_RGB24
<< QVideoFrame::Format_RGB565
<< QVideoFrame::Format_RGB555
<< QVideoFrame::Format_ARGB8565_Premultiplied
<< QVideoFrame::Format_BGRA32
<< QVideoFrame::Format_BGRA32_Premultiplied
<< QVideoFrame::Format_BGR32
<< QVideoFrame::Format_BGR24
<< QVideoFrame::Format_BGR565
<< QVideoFrame::Format_BGR555
<< QVideoFrame::Format_BGRA5658_Premultiplied
<< QVideoFrame::Format_AYUV444
<< QVideoFrame::Format_AYUV444_Premultiplied
<< QVideoFrame::Format_YUV444
<< QVideoFrame::Format_YUV420P
<< QVideoFrame::Format_YV12
<< QVideoFrame::Format_UYVY
<< QVideoFrame::Format_YUYV
<< QVideoFrame::Format_NV12
<< QVideoFrame::Format_NV21
<< QVideoFrame::Format_IMC1
<< QVideoFrame::Format_IMC2
<< QVideoFrame::Format_IMC3
<< QVideoFrame::Format_IMC4
<< QVideoFrame::Format_Y8
<< QVideoFrame::Format_Y16
<< QVideoFrame::Format_Jpeg
<< QVideoFrame::Format_CameraRaw
<< QVideoFrame::Format_AdobeDng;
}
bool CameraFrameGrabber::present(const QVideoFrame &frame)
{
//qWarning() << "A frame";
if (frame.isValid()) {
//qWarning() << "Valid Frame";
QVideoFrame cloneFrame(frame);
cloneFrame.map(QAbstractVideoBuffer::ReadOnly);
const QImage image(cloneFrame.bits(),
cloneFrame.width(),
cloneFrame.height(),
QVideoFrame::imageFormatFromPixelFormat(cloneFrame .pixelFormat()));
qWarning() << "Is created image NULL?" << image.isNull();
if (!image.isNull())
emit nextFrameAsImage(image);
cloneFrame.unmap();
return true;
}
return false;
}
And this is is how I used it:
grabber = new CameraFrameGrabber(this);
connect(grabber,&CameraFrameGrabber::nextFrameAsImage,this,&QCmaraTest::on_newFrame);
QMediaPlayer *a = new QMediaPlayer(this);
QString url = "http://Admin:1234#10.255.255.67:8008";
a->setMedia(QUrl(url));
a->setVideoOutput(grabber);
a->play();
The problem is that the image that is created is null. As far as I can tell, this can only be because the frame is valid but does not contain data.
Any ideas what the problem could be?
Important Detail: If I set the stream to a QVideoWidget and simply show that, it works just fine.
So I found out what the problem was.
This:
QVideoFrame::imageFormatFromPixelFormat(cloneFrame .pixelFormat())
Was returning invalid format because the IP cam gave the format as a YUV format which QImage can't handle. The solution was to force the format and the only one I found that did not make the program crash was: QImage::Format_Grayscale8.
With that, it worked.

App crashes when I try to read QString from socket

I am trying to develop a Qt program using sockets for client and server communication. I need help with figuring out why my server crashes when the client connects and the server tries to get a QString?
I have this code on the server side:
void Client::onReadyRead() {
qDebug() << "On ready read!";
QDataStream in(mSocket);
in.setVersion(QDataStream::Qt_4_0);
for (;;) {
if(!mBlockSize) {
if (mSocket->bytesAvailable() < sizeof(quint16)) break;
in >> mBlockSize;
}
if(mSocket->bytesAvailable() < mBlockSize) break;
qDebug() << "Package was recieved!";
qDebug() << "Block size: " << mBlockSize;
if(Table::INVALID_ID == mUser.id()) {
QString authStr;
in >> authStr;
qDebug() << "Recieved account data: " << authStr;
}
mBlockSize = 0;
}
}
And on the client side:
void Client::onConnected()
{
qDebug() << "Connected!";
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
//Reserve 2 bytes
out << (quint16)0 << mEmail << "|" << mPassword;
//Back to the beginning
out.device()->seek(0);
//Write a block size
out << (quint16)(block.size() - sizeof(quint16));
mSocket->write(block);
}

QNetwork Reply from QNetworkAccessManager

The following code is from an example shows how to use QNetworkAccessManager to download things.
void Downloader::replyFinished (QNetworkReply *reply)
{
if(reply->error())
{
qDebug() << "ERROR!";
qDebug() << reply->errorString();
}
else
{
qDebug() << reply->header(QNetworkRequest::ContentTypeHeader).toString();
qDebug() << reply->header(QNetworkRequest::LastModifiedHeader).toDateTime().toString();
qDebug() << reply->header(QNetworkRequest::ContentLengthHeader).toULongLong();
qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
qDebug() << reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
QFile *file = new QFile("C:/Qt/Dummy/downloaded.txt");
if(file->open(QFile::Append))
{
file->write(reply->readAll());
file->flush();
file->close();
}
delete file;
}
reply->deleteLater();
}
My question is do we have to call reply->deleteLater(); here? If we don't call it, when we perform QNetworkAccessManager::get() call the second time, will the QNetworkReply* in the slot be the same QNetworkReply* ?
If you don't call deleteLater(), the QNetworkReply object will be leaked and its memory not freed. A second get() call will create a new QNetworkReply object.

QDialog show is does not happen immediately

I have a sever client application and in the beginning client loads data from server. I have a dialog showing status of getting data from server (has progress bar). But when I call the function the dialog appears with no contents in it with white background and suddenly changes to completed status.
void SystemScreen::loadServerData()
{
qDebug() << Q_FUNC_INFO << "Invoked";
if (NULL != mpDataManagerDlg)
{
qDebug() << Q_FUNC_INFO << "show progres screen";
mpDataManagerDlg->showScreen();
}
loadData();
qDebug() << Q_FUNC_INFO << "Exits";
}
void SystemScreen::loadData()
{
qDebug() << Q_FUNC_INFO << "Invoked";
if (NULL != mpDataManager)
{
mpDataManager->loadDataFromServer();
}
qDebug() << Q_FUNC_INFO << "Exits";
}
I feel that dialog is displayed only after loadData() function is completed. Is there any alternative to do this?
I used a timer to start
QTimer::singleShot(100, this, SLOT(loadData()));
But then I have some trouble in getting data. ie data is empty if I read suddenly.
EDIT:
void DataManagerDialog::setDefault()
{
qDebug() << Q_FUNC_INFO << "Invoked";
setProgressBar(0);
setProgressBarColor(false);
ui->deptFailButton->hide();
ui->deptOkButton->hide();
ui->deptLabel->setStyleSheet("color:gray");
ui->subGroupFailButton->hide();
ui->subGroupOkButton->hide();
ui->subGroupLabel->setStyleSheet("color:gray");
ui->itemFailButton->hide();
ui->itemOkButton->hide();
ui->itemLabel->setStyleSheet("color:gray");
ui->salesBtnFailButton->hide();
ui->salesBtnOkButton->hide();
ui->salesBtnLabel->setStyleSheet("color:gray");
qDebug() << Q_FUNC_INFO << "Exits";
}
void DataManagerDialog::alignCenter()
{
qDebug() << Q_FUNC_INFO << "Invoked";
QWidget *par = parentWidget();
if (par)
{
int x = width()/2;
int y = height()/2;
QPoint mid(mapToGlobal(QPoint(x, y)));
int px = par->width()/2;
int py = par->height()/2;
QPoint parMid(mapToGlobal(QPoint(px, py)));
move(parMid.x()-mid.x(), parMid.y()-mid.y());
}
qDebug() << Q_FUNC_INFO << "Exits";
}
void DataManagerDialog::showScreen()
{
setDefault();
alignCenter();
show();
}
You probably do not enter the event loop.
Try to call QCoreApplication::processEvents() from time to time in mpDataManager->loadDataFromServer() to update the GUI.
From the processEvents documentation :
You can call this function occasionally when your program is busy performing a long operation (e.g. copying a file).
Edit added after getting feedback from the comments
A better approach would be to send signals in your loadDataFromServer() method with the status information and have a slot listen to the signal and update the GUI.
Here a prototype illustrating the idea :
void mpDataManagerDlg::loadDataFromServer() {
while(true) {
// do some work
int progress = // some value
emit updateDialogSignal(progress);
}
}
// in your dialog class
public slots:
void DataManagerDialog::updateDialog(int progress) {
// update gui
}
More about signals and slots can be found here.

Resources