Working with files, cp1251 and utf-8 encodings - c++

Rigth now i have something like
QCoreApplication a(argc, argv);
QStringList argList = a.arguments();
if (argList.length() < 2 || argList.length() > 3)
{
QTextStream(stdout) << "Usage: toGift input_file [output_dir]\n";
return - 1;
}
For decoding Windows-1251 strings, but i still get wrong filename, which is passed through argv. The filename is in cyrillic. Can't firgure out what am i missing

Text encodings in Windows console applications is a hairy matter. Tip: use the arguments() member of your QApplication (QCoreApplication if it's a console executable), it retrieves the arguments directly in UTF-16 from Windows, without trying to decode it from the lossy local encoding used for argc/argv.

in the end it came to this:
QTextCodec *codec = QTextCodec::codecForName("Windows-1251");
if(codec == 0)
{
QTextStream(stdout) << "No codec was found" << endl;
}
QTextDecoder *decoder = codec->makeDecoder();
QString inp_fileName = QString(decoder->toUnicode(argv[1]));
................
QFile inp_file(inp_fileName);
if(!inp_file.open(inp_file.ReadOnly))
{
QTextStream(stdout) << "Could not open file for reading.\n" << inp_file.errorString() << endl;
return -3;
}
I still needed the decoder for further use.

Related

How to send string in utf-8 to irc server?

I have an irc bot written in c++ with the use of Qt library. I store console text input in std::string , and then i'm using QSocket to post it on irc chat. But the problem is im want to use special signs (polish letters), which dont appear properly on chat. What is the problem?
The way i use QSocketis:
void Socket::poster(const QByteArray send)
{
mSocket->write(send);
mSocket->flush();
mSocket->reset();
}
QByteArray i create from std::string and std::cin
he code's long so i only post the parts crucial for the specific functonality which fails
Socket class (which is the main class in the program, providing data to other classes):
#############################################################
protected:
QSslSocket *mSocket;
--------------------
connect(mSocket, SIGNAL(readyRead()),
this, SLOT(readyReady())
--------------------
//console input:
QThread *thread = new QThread;
consoleInput = new ConsoleInput();
consoleInput->startConsole(thread, mSocket);
consoleInput->moveToThread(thread);
thread->start();
-------------------
void Socket::readyReady()
{
QString data;
data2 = data;
mSocket->ReadOnly;
while(mSocket->canReadLine())
{
data = mSocket->readLine();
}
mSocket->reset();
}
---------------------
void Socket::poster(const QByteArray send) //sending to irc from many classes news, console itd
{
mSocket->write(send);
mSocket->flush();
mSocket->reset();
}
-------------------
ConsoleInput class (which takes console input, which is later sent to irc chat):
###############################
void ConsoleInput::run()
{
std::cout << "!ConsoleInput::run()" << "\n";
while(1){
std::string input;
std::getline(std::cin, input);
determineOption(input);
if(input[0] != '/' || input[0] != '\\')
postInput(input);
input.clear();
}
}
----------------------------------
void ConsoleInput::postInput(std::string &input)
{
if(input[0]=='/')
return; //this prevents bot poting "/command" to channel
std::string lineToPost;
std::cout << "!lineToPost - input " << input << "\n";
ColourManipulation c;
lineToPost = "PRIVMSG #grunge " + c.addColours(input) + "\r\n";
emit mySignal(QByteArray::fromStdString(lineToPost)); // problem
}
Make sure std::cin/cout can accept & show non-ascii characters
Check the code can accept & show non-ascii characters:
std::string input;
std::getline(std::cin, input);
std::cout << input;
If you don't have problems with non-ascii characters in console itself
You need:
Know in which encoding the data originally comes from console to std::string &input.
std::string type per se uses no encoding -- it will return the bytes
you put in it -
What encoding does std::string.c_str() use?.
Import the bytes into QString using necessary encoding convertion
Export the resulting QString to UTF-8 encoded QByteArray (QByteArray itself is just an array of bytes too).
Write the QByteArray to a socket.
You can write something like the following:
/*
From doc: QTextCodec::codecForLocale()
Returns a pointer to the codec most suitable for this locale.
The codec will be retrieved from ICU where that backend is in use,
otherwise it may be obtained from an OS-specific API.
In the latter case, the codec's name may be "System".
*/
QTextCodec *codec = QTextCodec::codecForLocale(); // In most cases, it is not UTF-8
// Or set the encoding explicitly:
//QTextCodec *codec = QTextCodec::codecForName("Shift-JIS"); // put your input encoding here
QTextDecoder *decoder = codec->makeDecoder();
QByteArray chunk = QByteArray::fromStdString(input);
QString string = decoder->toUnicode(chunk);
delete decoder;
emit mySignal(string.toUtf8());
Be note that you can avoid std::string and use QString only:
QString is more comfortable to use, and, once received the data correctly, it always stores data in the same known format internally, despite of std::string, which has no idea what data it stores.
How to read from console to QString directly:
QTextStream in(stdin);
in.setCodec(<your console codec>);
QString input = in.readLine();
See QTextCodec and QTextStream.
Read also The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

Qt and GSM encoding

Hi i am developping an open source sms application and i am using Qt. But now i have various problem with the encodings.
I am using this library for various pdu encoding and decoding https://sourceforge.net/projects/pdulib/
In gsm there 3 main encodings Default 7bit alphabet, UCS2 and 8bit data. So when For 7bit encoding the library expect std::string argument so i am passing it like this
QString message = lineEdit->toPlainText();
std::string msg_to_pass = message.toStdString();
The sms is correctly sended but when there is accent characters the sms arrives with bad characters like 'C?' the sign of bad charset/encoding. Note that it is the phone that show it. So decoding error is very low.
But when i am using the UCS2 encoding
QString message = lineEdit->toPlainText();
std::wstring msg_to_pass = message.toStdWString();
because the library requires std::wstring for UCS2 the characters with accent got printed well. But the problem is when i am decoding a sms received. I have modified function of this library to suit my needs but again characters with accent have a problem. Here is the function
template<class MsgT>
void PrintUserData(const MsgT& msg, QString &message)
{
if (MsgT::DefaultAlphabet == msg.alphabet())
{
message = QString::fromStdString(msg.template userData<typename MsgT::DefaultUserData>().userData());
std::cout << "User Data: " << msg.template userData<typename MsgT::DefaultUserData>().userData() << std::endl;
}
else if(MsgT::UCS2Alphabet == msg.alphabet())
{
QTextStream ts(stdout);
message = QString::fromStdWString( msg.template userData<typename MsgT::UCS2UserData>().userData());
qInfo()<< message;
std::wcout << L"User Data: " << msg.template userData<typename MsgT::UCS2UserData>().userData() << std::endl;
}
else if(MsgT::EightBitDataAlphabet == msg.alphabet())
{
qInfo()<< "3";
const std::vector<unsigned char>& data = msg.template userData<typename MsgT::EightBitUserData>().userData();
std::cout << "User Data: ";
PrintBinary(data.begin(), data.end());
std::cout << std::endl;
}
}
I have tested various pdu lib for C++ and this seems to be the best for me.
My think is that i am doing something bad with the std::string and std::wstring but i can't figure what.
Also i know that UCS2 is UTF-16 but i have read that there is small differences.
My locale is FR (French)
I am using Qt 5.9
Sorry for my english.

Call HPDF_SaveToFile() with japanese filename

Im trying to save one pdf in path that contains japanese username. In this case, HPDF_SaveToFile is doing crash my app on windows. Any options to compile or other thing? Any idea to support Unicode filenames with libhaur? I not want to create pdf with japanese encode, I want to write pdf with japanese filename.
A solution in Qt. If you use C++, you can use fstream/ofstream(::write). If you use C, you can use fwrite.
QFile file(path);
if (file.open(QIODevice::WriteOnly))
{
HPDF_SaveToStream(m_pdf);
/* get the data from the stream and write it to file. */
for (;;)
{
HPDF_BYTE buf[4096];
HPDF_UINT32 siz = 4096;
HPDF_STATUS ret = HPDF_ReadFromStream(m_pdf, buf, &siz);
if (siz == 0)
{
break;
}
if (-1 == file.write(reinterpret_cast<const char *>(buf), siz))
{
qDebug() << "Write PDF error";
break;
}
}
}
HPDF_Free(m_pdf);
Refrence: Libharu Usage examples

win32 C++ print string to printer

After a few days of searching the net on how exactly I can go about printing an arbitrary string to an arbitrary printer on windows, I finally came up with this code.
LPBYTE pPrinterEnum;
DWORD pcbNeeded, pcbReturned;
PRINTER_INFO_2 *piTwo = NULL;
HDC printer;
EnumPrinters(PRINTER_ENUM_LOCAL,NULL,2,NULL,0,&pcbNeeded,&pcbReturned);
pPrinterEnum = new BYTE[pcbNeeded];
if (!EnumPrinters(PRINTER_ENUM_LOCAL,NULL,2,pPrinterEnum,pcbNeeded,&pcbNeeded,&pcbReturned)) {
qDebug() << "In Print, could not enumerate printers";
} else {
piTwo = ((PRINTER_INFO_2*)pPrinterEnum);
for (int i = 0; i < pcbReturned; i++) {
QString name = QString::fromWCharArray(piTwo[i].pPrinterName);
if (this->m_printer_path == name) {
const WCHAR * driver = L"WINSPOOL\0";
printer = CreateDC(NULL,piTwo[i].pPrinterName,NULL,NULL);
}
}
}
if (printer == 0) {
qDebug() << "No Printer HDC";
return;
} else {
qDebug() << "Printer seems okay!";
}
qDebug() << "Starting Document";
DOCINFO di;
memset( &di, 0, sizeof( di ) );
di.cbSize = sizeof( di );
WCHAR * text = new WCHAR[ba.length()];
QString(ba).toWCharArray(text);
StartDoc(printer,&di);
qDebug() << "Writing text";
TextOut(printer,0, 0, text, ba.length());
qDebug() << "Text Written";
EndPage(printer);
qDebug() << "Page ended";
DeleteDC(printer);
qDebug() << "DC Deleted";
Some basic caveats:
1) I cannot use QPrinter. I need to write raw text, no postscript.
2) I do not know the name of the printer until the user sets it, and I do not know the size of the string to print until the user creates it.
Additional information:
a) The printer works, I can print from Notepad, Chrome, just about everything to the printer that I want.
b) I am willing to implement just about any hack. Ones like write it to a text file and issue the copy command don't seem to work, that is, I get a failed to initialize device error.
This works:
notepad /P Documents/test_print.txt
This does not work:
copy Documents\test_print.txt /D:EPSON_TM_T20
copy Documents\test_print.txt /D \MYCOMPUTER\epson_tm_t20 (leads to access denied, printer is shared)
print Documents\test_print.txt (Unable to initialize device)
I have tried just about every recommended way to print a text file from the command line, just doesn't work. I have installed, reinstalled driver, added printer, mucked with ports and done it all again.
Obviously there is something simple about windows printing that I am missing due to inexperience.
What I want to accomplish is:
1) Best Scenario( Directly write text to the printer)
2) Second best scenario (Write text to a file, then execute some program to print it for me) Notepad adds an annoying amount of space to the bottom of the printout wasting paper.
Since the program is for end users, I have to find a way to do this automagically for them, so I can't expect them to click checkbox a in tab 36 after running command obscure_configuration from a powershell.
Any help would be greatly appreciated.
/Jason
UPDATE
This is the working code, before I go through an spruce it up a bit, which prints the contents of a QByteArray to a thermal printer.
qDebug() << "Executing windows code";
BOOL bStatus = FALSE;
DOC_INFO_1 DocInfo;
DWORD dwJob = 0L;
DWORD dwBytesWritten = 0L;
HANDLE hPrinter;
wchar_t * name = new wchar_t[this->m_printer_path.length()+1];
this->m_printer_path.toWCharArray(name);
name[this->m_printer_path.length() + 1] = 0;
qDebug() << "opening printer";
bStatus = OpenPrinter(name,&hPrinter, NULL);
if (bStatus) {
qDebug() << "Printer opened";
DocInfo.pDocName = L"My Document";
DocInfo.pOutputFile = NULL;
DocInfo.pDatatype = L"RAW";
dwJob = StartDocPrinter( hPrinter, 1, (LPBYTE)&DocInfo );
if (dwJob > 0) {
qDebug() << "Job is set.";
bStatus = StartPagePrinter(hPrinter);
if (bStatus) {
qDebug() << "Writing text to printer";
bStatus = WritePrinter(hPrinter,ba.data(),ba.length(),&dwBytesWritten);
EndPagePrinter(hPrinter);
} else {
qDebug() << "could not start printer";
}
EndDocPrinter(hPrinter);
qDebug() << "closing doc";
} else {
qDebug() << "Couldn't create job";
}
ClosePrinter(hPrinter);
qDebug() << "closing printer";
} else {
qDebug() << "Could not open printer";
}
if (dwBytesWritten != ba.length()) {
qDebug() << "Wrong number of bytes";
} else {
qDebug() << "bytes written is correct " << QString::number(ba.length()) ;
}
Note: I do owe an apology to Skizz, what he wrote was actually helpful in debugging the fundamental issue. The characters in the QByteArray are preformatted specifically for the printer, the problem is, they contain several NULL bytes. When trying to send them to the printer, this causes TextOut to truncate the text, only printing the first few lines. Using WritePrinter, as suggested in the answer ignores null bytes and accepts a void * and a length, and just puts it all there.
Further, his response recommending the use of PrintDlg did work to fectch the correct printer HDC, the issus is that, the user first chooses a printer once, and then doesn't need to choose it each time they print, because they will be printing alot (It's a Point of Sale).
The problem with getting the printer HDC from the string name was due to not adding the all important NULL byte to wchar_* which was solved this way:
wchar_t * name = new wchar_t[this->m_printer_path.length()+1];
this->m_printer_path.toWCharArray(name);
name[this->m_printer_path.length() + 1] = 0;
In the above, m_printer_path is a string representation of the name of the printer taken from Print Manager.
Because the string has all the formatting necessary for the printer, there's no need to worry about new lines, or any formatting.
All three answers to this question were actually very helpful in implementing the final working solution, and I have voted up each answer, and I appreciate the time each person took in responding.
Most modern printers don't perform any form of layout processing of the data they are given. Thus, sending a sequence of characters to the printer would, at best, just print a line of text running off the side of the page in some default font. Carriage returns may work too.
What modern printers usually do is print pages using preprocessed data that the printer understands and defines what to print where and how to print it. All this preprocessing is done on the host PC and the results sent to the printer. This is why you usually install printer drivers - these drivers take the user data (whether it's a simple text file or a DTP page) and converts it into a language the printer understands.
The upshot of this is that sending raw text to the printer probably won't work.
Then you've got the problem of having multiple printers with different properties and languages.
So, in Windows, all this is abstracted into the printer device context object. This has the same interface as a graphics device context but you create it differently.
The Win32 API has a common dialog to let the user choose the printer. Use the PrintDlgEx function to allow the user to choose a printer. Then use the returned DC to draw text to the page.
There are a couple of MSDN articles describing how to send raw data (printer control codes, etc.) to a printer.
How To: Send Data Directly to a GDI Printer
How To: Send Data Directly to an XPS Printer
You have the right idea (though you should have StartPage and EndDoc calls to match up). The problem is that TextOut draws only a line of text. It won't break long strings into multiple lines, etc. You need to do that (or find code to do it).
If you know that the text will always fit on a single page, you could probably replace your TextOut with a DrawTextEx call, which can do basic line breaking, tab expansion, etc.
Why not try QPrint.. it prints raw text using a Generic Text Only driver
QString prn("^XA^FO121,41^A0N,19,15^FDABC DEFGHIJKLMNOPQRSTUVWXYZ^FS^XZ");
QPrinter printer(QPrinterInfo::defaultPrinter()); //the default printer is "Generic / Text Only"
QTextDocument doc(prn);
doc.print(&printer);
MTry the following code in C++:
#include<fstream>
Class PrinterDriver{
Private:
fstream print("PRN")
Public:
Void Print(char a[]){
print >>a;}
Char GetPrinterStatus[](){
char c[];
print<<c;
return c;}};
understand it(key)

How to print to console when using Qt

I'm using Qt4 and C++ for making some programs in computer graphics. I need to be able to print some variables in my console at run-time, not debugging, but cout doesn't seem to work even if I add the libraries. Is there a way to do this?
If it is good enough to print to stderr, you can use the following streams originally intended for debugging:
#include<QDebug>
//qInfo is qt5.5+ only.
qInfo() << "C++ Style Info Message";
qInfo( "C Style Info Message" );
qDebug() << "C++ Style Debug Message";
qDebug( "C Style Debug Message" );
qWarning() << "C++ Style Warning Message";
qWarning( "C Style Warning Message" );
qCritical() << "C++ Style Critical Error Message";
qCritical( "C Style Critical Error Message" );
// qFatal does not have a C++ style method.
qFatal( "C Style Fatal Error Message" );
Though as pointed out in the comments, bear in mind qDebug messages are removed if QT_NO_DEBUG_OUTPUT is defined
If you need stdout you could try something like this (as Kyle Strand has pointed out):
QTextStream& qStdOut()
{
static QTextStream ts( stdout );
return ts;
}
You could then call as follows:
qStdOut() << "std out!";
I found this most useful:
#include <QTextStream>
QTextStream out(stdout);
foreach(QString x, strings)
out << x << endl;
Writing to stdout
If you want something that, like std::cout, writes to your application's standard output, you can simply do the following (credit to CapelliC):
QTextStream(stdout) << "string to print" << endl;
If you want to avoid creating a temporary QTextStream object, follow Yakk's suggestion in the comments below of creating a function to return a static handle for stdout:
inline QTextStream& qStdout()
{
static QTextStream r{stdout};
return r;
}
...
foreach(QString x, strings)
qStdout() << x << endl;
Remember to flush the stream periodically to ensure the output is actually printed.
Writing to stderr
Note that the above technique can also be used for other outputs. However, there are more readable ways to write to stderr (credit to Goz and the comments below his answer):
qDebug() << "Debug Message"; // CAN BE REMOVED AT COMPILE TIME!
qWarning() << "Warning Message";
qCritical() << "Critical Error Message";
qFatal("Fatal Error Message"); // WILL KILL THE PROGRAM!
qDebug() is closed if QT_NO_DEBUG_OUTPUT is turned on at compile-time.
(Goz notes in a comment that for non-console apps, these can print to a different stream than stderr.)
NOTE: All of the Qt print methods assume that const char* arguments are ISO-8859-1 encoded strings with terminating \0 characters.
Add this to your project file:
CONFIG += console
What variables do you want to print? If you mean QStrings, those need to be converted to c-Strings. Try:
std::cout << myString.toAscii().data();
It also has a syntax similar to prinft, e.g.:
qDebug ("message %d, says: %s",num,str);
Very handy as well
Go the Project's Properties -> Linker-> System -> SubSystem, then set it to Console(/S).
What about including iostream library and precise that cout is an object of std like this :
#include <iostream>
std::cout << "Hello" << std::endl;
If you are printing to stderr using the stdio library, a call to fflush(stderr) should flush the buffer and get you real-time logging.
Well, after studying several examples on the Internet describing how to output messages from a GUI in Qt to stdout, I have refined a working stand-alone example on redirecting messages to a console, via qDebug() and installing qInstallMessageHandler(). The console will be showed at the same time as the GUI and can be hidden if deemed necessary. The code is easy to integrate with existing code in your project. Here is the full sample and feel free to use it in any way as you like, as long as you adhere to the License GNU GPL v2. You have to use a form of some sort and a MainWindow I think - otherwise the sample will run, but probably crash when forced to quit. Note: there is no way to quit via a close button or a menu close because I have tested those alternatives and the application will crash eventually every now and then. Without the close button the application will be stable and you can close it down from the main window. Enjoy!
#include "mainwindow.h"
#include <QApplication>
//GNU GPL V2, 2015-02-07
#include <QMessageBox>
#include <windows.h>
#define CONSOLE_COLUMNS 80
#define CONSOLE_ROWS 5000
#define YOURCONSOLETITLE "Your_Console_Title"
typedef struct{
CONSOLE_SCREEN_BUFFER_INFOEX conScreenBuffInfoEX;
HANDLE con_screenbuf;
HWND hwndConsole;
HMENU consoleMenu ;
QString consoleTitle;
QMessageBox mBox;
QString localMsg;
QString errorMessage;
WINBOOL errorCode;
} consoleT;
static consoleT *console;
BOOL WINAPI catchCTRL( DWORD ctrlMsg ){
if( ctrlMsg == CTRL_C_EVENT ){
HWND hwndWin = GetConsoleWindow();
ShowWindow(hwndWin,SW_FORCEMINIMIZE);
}
return TRUE;
}
void removeCloseMenu(){
int i;
for( i = 0; i < 10; i++){
console->hwndConsole = FindWindowW( NULL, console->consoleTitle.toStdWString().data());
if(console->hwndConsole != NULL)
break;
}
if( !(console->errorCode = 0) && (console->hwndConsole == NULL))
console->errorMessage += QString("\nFindWindowW error: %1 \n").arg(console->errorCode);
if( !(console->errorCode = 0) && !(console->consoleMenu = GetSystemMenu( console->hwndConsole, FALSE )) )
console->errorMessage += QString("GetSystemMenu error: %1 \n").arg(console->errorCode);
if(!(console->errorCode = DeleteMenu( console->consoleMenu, SC_CLOSE, MF_BYCOMMAND )))
console->errorMessage += QString("DeleteMenu error: %1 \n").arg(console->errorCode);
}
void initialiseConsole(){
console->conScreenBuffInfoEX.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
console->consoleMenu = NULL;
console->consoleTitle = YOURCONSOLETITLE;
console->con_screenbuf = INVALID_HANDLE_VALUE;
console->errorCode = 0;
console->errorMessage = "";
console->hwndConsole = NULL;
console->localMsg = "";
if(!(console->errorCode = FreeConsole()))
console->errorMessage += QString("\nFreeConsole error: %1 \n").arg(console->errorCode);
if(!(console->errorCode = AllocConsole()))
console->errorMessage += QString("\nAllocConsole error: %1 \n").arg(console->errorCode);
if( (console->errorCode = -1) && (INVALID_HANDLE_VALUE ==(console->con_screenbuf = CreateConsoleScreenBuffer( GENERIC_WRITE | GENERIC_READ,0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL))))
console->errorMessage += QString("\nCreateConsoleScreenBuffer error: %1 \n").arg(console->errorCode);
if(!(console->errorCode = SetConsoleActiveScreenBuffer(console->con_screenbuf)))
console->errorMessage += QString("\nSetConsoleActiveScreenBuffer error: %1 \n").arg(console->errorCode);
if(!(console->errorCode = GetConsoleScreenBufferInfoEx(console->con_screenbuf, &console->conScreenBuffInfoEX)))
console->errorMessage += QString("\nGetConsoleScreenBufferInfoEx error: %1 \n").arg(console->errorCode);
console->conScreenBuffInfoEX.dwSize.X = CONSOLE_COLUMNS;
console->conScreenBuffInfoEX.dwSize.Y = CONSOLE_ROWS;
if(!(console->errorCode = SetConsoleScreenBufferInfoEx(console->con_screenbuf, &console->conScreenBuffInfoEX)))
console->errorMessage += QString("\nSetConsoleScreenBufferInfoEx error: %1 \n").arg(console->errorCode);
if(!(console->errorCode = SetConsoleTitleW(console->consoleTitle.toStdWString().data())))
console->errorMessage += QString("SetConsoleTitle error: %1 \n").arg(console->errorCode);
SetConsoleCtrlHandler(NULL, FALSE);
SetConsoleCtrlHandler(catchCTRL, TRUE);
removeCloseMenu();
if(console->errorMessage.length() > 0){
console->mBox.setText(console->errorMessage);
console->mBox.show();
}
}
void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg){
if((console->con_screenbuf != INVALID_HANDLE_VALUE)){
switch (type) {
case QtDebugMsg:
console->localMsg = console->errorMessage + "Debug: " + msg;
WriteConsoleW(console->con_screenbuf, console->localMsg.toStdWString().data(), console->localMsg.toStdWString().length(), NULL, NULL );
WriteConsoleA(console->con_screenbuf, "\n--\n", 4, NULL, NULL );
break;
case QtWarningMsg:
console->localMsg = console->errorMessage + "Warning: " + msg;
WriteConsoleW(console->con_screenbuf, console->localMsg.toStdWString().data(), console->localMsg.toStdWString().length() , NULL, NULL );
WriteConsoleA(console->con_screenbuf, "\n--\n", 4, NULL, NULL );
break;
case QtCriticalMsg:
console->localMsg = console->errorMessage + "Critical: " + msg;
WriteConsoleW(console->con_screenbuf, console->localMsg.toStdWString().data(), console->localMsg.toStdWString().length(), NULL, NULL );
WriteConsoleA(console->con_screenbuf, "\n--\n", 4, NULL, NULL );
break;
case QtFatalMsg:
console->localMsg = console->errorMessage + "Fatal: " + msg;
WriteConsoleW(console->con_screenbuf, console->localMsg.toStdWString().data(), console->localMsg.toStdWString().length(), NULL, NULL );
WriteConsoleA(console->con_screenbuf, "\n--\n", 4, NULL, NULL );
abort();
}
}
}
int main(int argc, char *argv[])
{
qInstallMessageHandler(messageHandler);
QApplication a(argc, argv);
console = new consoleT();
initialiseConsole();
qDebug() << "Hello World!";
MainWindow w;
w.show();
return a.exec();
}
"build & run" > Default for "Run in terminal" --> Enable
to flush the buffer use this command --> fflush(stdout);
you can also use "\n" in printf or cout.
For Qt5 QString must be converted, for example:
QString sResultText = lblLineEdit->text(); //<--text from QLineEdit
qInfo(sResultText.toUtf8().data()); //<--show converted result