Why qDebug and QLabel don't show unicode? - c++

I have a byteArray with 2 bytes. Those 2 bytes in UTF-8 mean "Š" ( one letter ) and in windows-1250 they mean "Š" ( two letters ), so they are properly in these two encodings.
My code:
QByteArray byteArray;
byteArray.append(0xC2);
byteArray.append(0x8A);
QTextStream textStreamUTF(byteArray);
textStreamUTF.setCodec(QTextCodec::codecForName("UTF-8"));
QString stringUTF = textStreamUTF.readLine();
QTextStream textStreamAnsi(byteArray);
textStreamAnsi.setCodec(QTextCodec::codecForLocale());
QString stringAnsi = textStreamAnsi.readLine();
qDebug()<<stringUTF<<stringAnsi;
In debug I see: "\u008A" "Š" , so stringAnsi is correctly displayed. StringUTF is properly set ( \u008A is Š ), but it isn't correctly displayed ( I would like to see "Š" ).
The same with QLabels and setText. When I set stringAnsi, I see on the screen good characters. When I set stringUTF I see nothing.

Related

How to set up stylesheet in QT to choose random image for wiget background?

So I'm trying to choose random image from file system of my pc and make it background in wiget. So thats why I'm opening QFileDialog and using it. qDebug gives me right path to the image, but still it doesn't work.
void ChatWindow::on_actionImage_triggered()
{
QString fileName = QFileDialog::getOpenFileName(
this, tr("Open file"), "/home", tr("Images(*.jpg)")
);
QString filePath(fileName);
qDebug () << filePath;
setStyleSheet(
"ChatWindow{border-image:url(:" +
filePath +
") 0 0 0 0 stretch stretch;}"
);
QGraphicsOpacityEffect * effect1 =
new QGraphicsOpacityEffect(ui->messageHistory);
effect1->setOpacity(0.8);
ui->messageHistory->setGraphicsEffect(effect1);
ui->messageHistory->setStyleSheet("background-color: white;");
QGraphicsOpacityEffect * effect2 =
new QGraphicsOpacityEffect(ui->roomTree);
effect2->setOpacity(0.8);
ui->roomTree->setGraphicsEffect(effect2);
ui->roomTree->setStyleSheet("background-color: white;");
QGraphicsOpacityEffect * effect3 =
new QGraphicsOpacityEffect(ui->messageInput);
effect3->setOpacity(0.8);
ui->messageInput->setGraphicsEffect(effect3);
ui->sendButton->setStyleSheet("background-color: none;");
}
I've seen this one Unable to set the background image in Qt Stylesheet related to my problem, but in my case it doesn't work.
According to the documentation, there is no such property called border-image: what you're searching for is background-image.
Moreover, since you're also specifying other background's parameters, you should use background.
Moreover, since your file is on the disk and not in the resources, the url should not start with :: type url(" + filePath + ") instead of url(:" + filePath + ").
The corrected syntax:
setStyleSheet(
"ChatWindow{background:url(" +
filePath +
") 0 0 0 0 stretch stretch;}"
);

QT - How set filename encoding to cyrillic

when creating a file named "абцде"
the filename is written with hieroglyphics
const QByteArray data = "someData"; // some Data
QString fileName = "абцде.txt"; // fileName
QFile localFile(fileName.toUtf8());
localFile.open(QIODevice::WriteOnly);
localFile.write(data);
localFile.close();
These lines of code form qt man on internationalization
can help. ( QString use Unicode originally ).
QTextCodec *codec = QTextCodec::codecForName( "Windows-1251" );
QByteArray encodedString = codec->fromUnicode( "абцде.txt" );
You might need to play around with encodings ( "Windows-1251" ), kind of brute force method.
If your sources are UTF8 encoded, then you should use this (Qt Documentation)
QString fileName = QString::fromUtf8( "абцде.txt" ); // fileName
If your sources has other encoding then you can select other functions like QString::fromLocal8Bit.

print QPlainTextEdit document plain text only

I'm wondering how to print the document of a QPlainTextEdit component without any colors, backgrounds or formats ( plain text only ). The code I have is printing the background ( white on black in my case ).
QPrinter printer;
QPrintDialog dialog( &printer, NULL );
dialog.setWindowTitle( tr( "Print Content" ) );
if ( isSelection ) {
dialog.addEnabledOption( QAbstractPrintDialog::PrintSelection );
}
if ( dialog.exec() == QDialog::Accepted ) {
document->print(&printer);
}
Any ideas ?? Thanks in advance !
Use this:
QPrinter printer(QPrinter::HighResolution);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName("output.pdf");
QString buffer = ui->plainTextEdit->document()->toHtml();
ui->plainTextEdit->setPlainText(ui->plainTextEdit->toPlainText());
ui->plainTextEdit->document()->print(&printer);
ui->plainTextEdit->clear();
ui->plainTextEdit->appendHtml(buffer);
The main idea is to print only plainText without formatting, but set normal formatted text after printing, so user will not lose formatted data.
I thought about improvement, so I wrote also this:
QPrinter printer(QPrinter::HighResolution);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName("output.pdf");
QTextDocument *buffer = ui->plainTextEdit->document()->clone();
buffer->setPlainText(ui->plainTextEdit->toPlainText());
buffer->print(&printer);
Why is it better? We clone QTextDocument *buffer so we work with this new document. Our plainTextEdit remains untouchable, so user will not see unformatted text while print. But don't forget delete buffer When you don't need this clone aby more.
Result:
In pdf:
As you can see, there is no formatting.

Qt: Print raw text

I need to output a ZPL script to a Zebra printer in a Qt application.
The printer is on a smb share network configured as raw printer in the client computer.
Everything goes fine if I call cupsPrintFile( "printer_name", "./tmp_print_file.zpl", "", 0, NULL ) from a C++ test program.
If I use QTextDocument::print() using the same text in "./tmp_print_file.zpl" as document, nothing gets printed.
I sniffed the network and found that the data being sent to the printer server is not raw data, but, a postscript!
Is there any way to get the data sent to the printer with no modification at all?
Let me be clear that I don't want to render a text, but just send the label script, that is ready to print, directly to the printer, that understands the ZPL protocol.
Thanks for all.
EDIT:
As #Martin said, I tried:
printer.setOutputFormat( QPrinter::NativeFormat );
QTextDocument *doc = new QTextDocument( QString( label ), this );
doc->print( &printer );
but it didn't work.
Before I start, must thank Dave. His suggestion to bypass the temporary file while printing with CUPs works fine.
Now, my conclusion: There is no easy way to print raw data using Qt only.
Maybe creating custom QPainter or going down to the bits of QPrinter could give a solution, but it would take me too much time.
The final solution is simply use CUPs API inside my Qt application. Unfortunatelly, it is not portable.
Here is a snippet:
#include <cups/cups.h>
//...
int print_label( const char *text, const char *printer_name, const char *job_name )
{
int jobId = 0;
jobId = cupsCreateJob( CUPS_HTTP_DEFAULT, printer_name, job_name, 0, NULL );
if ( jobId > 0 )
{
qDebug( ) << "Printing job #" << jobId << " (\"" << job_name << "\").";
const char* format = CUPS_FORMAT_TEXT; // CUPS_FORMAT_POSTSCRIPT;
cupsStartDocument( CUPS_HTTP_DEFAULT, printer_name, jobId, text, format, true );
cupsWriteRequestData( CUPS_HTTP_DEFAULT, text, strlen( text ) );
cupsFinishDocument( CUPS_HTTP_DEFAULT, printer_name );
}
return jobId;
}
//...
// Now, inside any Qt function (may be a slot):
QPrinter printer;
QPrintDialog *dialog = new QPrintDialog( &printer, this );
dialog->setWindowTitle( tr( "Zebra label" ) );
if ( dialog->exec( ) != QDialog::Accepted )
return;
// This is the sample label. Can be anything.
const char label[] =
"^XA~TA000~JSN^LT0^MNW^MTD^PON^PMN^LH0,0^JMA^PR4,4^MD0^JUS^LRN^CI0^XZ\n"
"^XA\n"
"^MMT\n"
"^LL0600\n"
"^PW900\n"
"^LS0\n"
"^BY2,3,54^FT24,109^BCN,,Y,N\n"
"^FD>;43210000>773>0000^FS\n"
"^PQ1,0,1,Y^XZ\n";
// Informative only.
ui->txtLabelScript->setPlainText( label );
// Call the printing function.
if ( print_label( label, printer.printerName( ).toAscii( ), "Zebra_Label" ) == 0 )
qDebug( ) << "CUPS Error: " << ippErrorString( cupsLastError( ) );
And it's done.
Don't forget to link libcups (-lcups).
I still hope any buddy to add another solution prooving that Qt-only is possible. Meanwhile, it is enough.
Thanks everybody.
Could you just do exactly what you did in your test program:
Create a temporary file (QTemporaryFile).
Send the contents to the file.
Call your cupsPrintFile method.
Or there is probably a way with the CUPS API to bypass the temporary file. Disclaimer: I have absolutely no experience with the CUPS API; this is just based on a cursory look at some online documentation. Looks like perhaps the following sequence:
cupsCreateJob > cupsStartDocument > cupsWriteRequestData > cupsFinishDocument
If that works, you just need to convert your QString to the correct byte encoding.
Thanks for fljx's code, it is very useful for me.
I changed a litte for sending raw text to zebra printer .
const char* format = CUPS_FORMAT_RAW;
Take a look at QPrinter(),
QTextDocument is designed to render formatted text.

Icon click on Qt QTreeWidget

I have a treewidget in my Qt form. It shows a tree of files, showing a icon representing something about them, and their name.
I entered these using treeItem->setIcon(0, *icon), and treeItem->setText(0, text) .
The reason I entered both values to the same column (0), is because otherwise the icons would not stay next to the text, rather always stick to the left, even when the text was indented to the right (because it's a child of another item).
The problem is, now I can't tell if the user clicked on the icon or on the text itself, and I need to deal with these separately.
So, is there anyway to get more info than just the treeitem and column when an object in a treewidget is clicked,
or is there any way to put them on seperate columns and still have the normal behavior icons and text should have?
Thanks.
I don't think there is a straight forward way to get more info, if you are simply using the clicked() or itemClicked() signals. You probably have to create a custom class that inherits QTreeWidget, and reimplement one of the virtual mouse-event functions.
mouseMoveEvent ( QMouseEvent * )
mousePressEvent ( QMouseEvent * )
mouseReleaseEvent ( QMouseEvent * )
This is not something I would recommend, unless you really know what you are doing, and really need to do it.
However, I can't remember seeing a list widget anywhere, where clicking an icon is handled differently from clicking the text in the same column. So if you are looking for "the normal behavior icons and text should have", you probably should look for another solution.
I found the following solution for this problem:
void MyTreeWidget::mousePressEvent( QMouseEvent* aEvent )
{
QTreeWidget::mousePressEvent( aEvent );
const QPoint clickedPosition = aEvent->pos();
const QRect itemRectangle = visualItemRect( itemAt( clickedPosition ) );
const int iconOffset = itemRectangle.height() - iconSize().height();
QRect iconRectangle;
iconRectangle.setTopLeft( itemRectangle.topLeft() + QPoint( iconOffset, iconOffset ) );
iconRectangle.setWidth( iconSize().width() );
iconRectangle.setHeight( iconSize().height() );
if ( iconRectangle.contains( clickedPosition ) )
{
qDebug() << "ICON clicked";
// Emit an icon clicked SIGNAL.
}
}