Qt ব্যবহার করার সময় কীভাবে কনসোলে মুদ্রণ করবেন


159

কম্পিউটার গ্রাফিক্সে কিছু প্রোগ্রাম তৈরি করার জন্য আমি Qt4 এবং C ++ ব্যবহার করছি। রান-টাইমে আমার কনসোলে কিছু ভেরিয়েবল মুদ্রণ করতে সক্ষম হওয়া দরকার, ডিবাগিং নয়, তবে coutআমি লাইব্রেরিগুলি যুক্ত করলেও কাজ করে না বলে মনে হচ্ছে। এই কাজ করতে একটি উপায় আছে কি?


3
আপনি কি কাউট সম্পর্কে কাজ করতে পারেন তা বিশদভাবে বলতে পারেন কারণ এটি অবশ্যই কাজ করা উচিত। আপনি কি একটি সংকলন ত্রুটি পান? আপনি কি কাউটের একটি কোড উদাহরণ দেখাতে পারেন যা আপনার পক্ষে কাজ করে না? আপনি কীভাবে অ্যাপ্লিকেশনটি চালাচ্ছেন তাও ব্যাখ্যা করুন। আপনি কি এটি কোনও কনসোল থেকে বা কোনও আইডিইর মধ্যে থেকে চালাচ্ছেন এবং এর আউটপুট উইন্ডোতে আউটপুট দেখছেন না?
আর্নল্ড স্পেন্স

কেবল সম্পূর্ণতার জন্য: @ আর্নল্ডস্পেন্স - লাইব্রেরি ছাড়া, আমি পাই error: ‘cout’ was not declared in this scope; iostream সঙ্গে, আমি পেতে error: no match for ‘operator<<’ in ‘std::operator<< [with _Traits = std::char_traits<char>](((std::basic_ostream<char>&)(& std::cout)), ...; পরিবর্তে উত্তরে কমান্ড ব্যবহার করে ভাল কাজ করে।
sdaau

যখন সমস্যার বিবৃতিটি সহজভাবে হয়, "এটি কাজ করে না" তখন সমাধানগুলি সরবরাহ করা কঠিন। আপনি কী প্রত্যাশা করেছিলেন এবং কীভাবে আসল ফলাফল থেকে পৃথক হয়েছে তার আরও সম্পূর্ণ বিবরণ দিতে দয়া করে আপনার প্রশ্নটি সম্পাদনা করুন। দেখুন কিভাবে জিজ্ঞাসা করতে কি একটি ভাল ব্যাখ্যা করে তোলে নির্দেশ জন্য।
টবি স্পিড

এই ক্ষেত্রে, আপনার স্পষ্টভাবে উল্লেখ করা উচিত যে সেই "ভেরিয়েবলগুলি" Qt- নির্দিষ্ট অবজেক্ট (যেমন QString)।
ব্যবহারকারী 202729

উত্তর:


203

এটি মুদ্রণের জন্য যদি যথেষ্ট ভাল হয় তবে stderrআপনি নিম্নলিখিত স্রোতগুলি মূলত ডিবাগিংয়ের উদ্দেশ্যে ব্যবহার করতে পারেন:

#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" );

মন্তব্যগুলিতে যেমন উল্লেখ করা হয়েছে তবুও, মনে রাখবেন QDebug বার্তাগুলি QT_NO_DEBUG_OUTPUTসংজ্ঞায়িত করা থাকলে মুছে ফেলা হবে

আপনার যদি স্টডআউট দরকার হয় তবে আপনি এই জাতীয় কিছু চেষ্টা করতে পারেন (যেমন কাইল স্ট্র্যান্ড নির্দেশ করেছেন):

QTextStream& qStdOut()
{
    static QTextStream ts( stdout );
    return ts;
}

তারপরে আপনি নীচের মত কল করতে পারেন:

qStdOut() << "std out!";

1
আমি জিজ্ঞাসা করেছি, ডিবাগিংয়ের সময় একটি ফাংশন থাকতে হবে যা আমাকে রানটাইম চলাকালীন কনসোলে বার্তা লিখতে দেয়, ডিবাগিংয়ের সময় নয়।
লেসোলোরাজানভ

11
এর নাম সত্ত্বেও, এই ফাংশনটি ডিবাগারের সাথে ডিবাগিংয়ের সাথে সম্পর্কিত নয়। এটি একটি সুবিধাজনক ফাংশন যা কিউটি স্টডারারে আউটপুট প্রেরণের জন্য সরবরাহ করে যা সংজ্ঞায়িত সংজ্ঞা থেকে মুছে ফেলা যায়। সুতরাং এটি রানটাইমে কনসোলে আউটপুট অর্জনের জন্য বিকল্প।
আর্নল্ড স্পেন্স

আপনাকে অনেক ধন্যবাদ, আমি এটি ব্যবহার করছি :)। আমার ধারণা আমার তখন যে কোডটি ব্যবহার করা হয়েছে তার কোনওটি লেখার দরকার নেই। ধন্যবাদ! এটি দুর্দান্ত ব্যবহারযোগ্য হয়েছে।
লেসোলোরাজানভ

51
# অন্তর্ভুক্ত <QDebug>
আদরের সন্বোধনবিশেষ

62
সমস্ত কনসোল আউটপুট জন্য দয়া করে qDebug ব্যবহার করবেন না। এটি কেবল সত্য ডিবাগ প্রিন্টগুলির জন্য ত্রুটি এবং সতর্কতার জন্য qWarning, qCritical এবং qFatal ব্যবহার করুন। কারণ QDebug স্টেটমেন্টগুলি পারফরম্যান্স সংরক্ষণ করতে এবং আউটপুট বিশৃঙ্খলা থেকে অ্যাপ্লিকেশনটি বন্ধ করতে QT_NO_DEBUG_OUTPUT এর সাথে সংকলন করার সময় অপসারণ করা যেতে পারে।
জাস্টম্যাক্সিমিয়াম পাওয়ার ower

150

আমি দেখেছি এই সবচেয়ে দরকারী:

#include <QTextStream>

QTextStream out(stdout);
foreach(QString x, strings)
    out << x << endl;

14
উত্তর কেন গৃহীত হয় তা আমি জানি না, তবে এটি অবশ্যই সবচেয়ে কার্যকর।
সেমিওন ডানিলভ

4
একমত। stderr, ভাল, ত্রুটি (এবং ডিবাগিং) এর জন্য। এটি গ্রহণযোগ্য উত্তর হওয়া উচিত কারণ এটি কেবলমাত্র স্ট্যান্ডআউট এবং কিউটি ব্যবহার করে।
মার্শাল ইউবাঙ্কস

1
এইটি আমার পক্ষে কাজ করেছিল - এবং মনে হয়েছিল কাউটের মাধ্যমে আউটপুট তথ্য দেওয়ার সঠিক উপায়
মাইকেল ভিনসেন্ট

2
যদি আপনি কীভাবে ত্রুটি / সতর্কতাগুলি মুদ্রণ করবেন সে সম্পর্কিত কিছু তথ্য সহ কিছুটা তথ্যের সাথে (দুঃখের সাথে গোজের উত্তরটি অনুপস্থিত তবে নীচের মন্তব্যে উপস্থিত রয়েছে) কী কী qDebug()ইত্যাদি সম্পর্কে তথ্য অন্তর্ভুক্ত করেন তবে এটিকে আরও উচ্চতর উত্তর দেওয়া হবে (আইএমও এটি ইতিমধ্যে উচ্চতর, যেহেতু ওপি প্রতিস্থাপনের জন্য কিছু std::coutচাইছে, তবে ৪০ জন ভোটার তাতে রাজি নয় বলে মনে হচ্ছে)
কাইল স্ট্র্যান্ড

QTextStream qStdout() { return {stdout}; }এটি মোড়ানো একটি দরকারী উপায় হতে পারে, qWarning()ইত্যাদি। সঙ্গে সামঞ্জস্যপূর্ণ এবং staticঅস্থায়ী স্ট্র্যামেজ এড়ানোর জন্য কিছু রাষ্ট্র হতে পারে?
ইয়াক্ক - অ্যাডাম নেভ্রামুমন্ট

36

লিখেছেন stdout

যদি আপনি এমন কিছু চান যা std::coutআপনার অ্যাপ্লিকেশনটির স্ট্যান্ডার্ড আউটপুটকে পছন্দ করে, আপনি কেবল নিম্নলিখিতটি করতে পারেন ( ক্যাপেলিকের কাছে ক্রেডিট ):

QTextStream(stdout) << "string to print" << endl;

যদি আপনি কোনও অস্থায়ী QTextStreamঅবজেক্ট তৈরি করা এড়াতে চান তবে এর staticজন্য একটি হ্যান্ডেল ফেরত দেওয়ার জন্য একটি ফাংশন তৈরি করার নীচে মন্তব্যে ইয়াককের পরামর্শ অনুসরণ করুন stdout:

inline QTextStream& qStdout()
{
    static QTextStream r{stdout};
    return r;
}

...

foreach(QString x, strings)
    qStdout() << x << endl;

মনে রাখবেন থেকে flushস্ট্রিম পর্যায়ক্রমে তা নিশ্চিত করার জন্য আউটপুট আসলে ছাপা হয়।

লিখেছেন stderr

নোট করুন যে উপরের কৌশলটি অন্যান্য আউটপুটগুলির জন্যও ব্যবহার করা যেতে পারে। তবে এখানে আরও পাঠযোগ্য পঠনযোগ্য উপায় রয়েছে stderr( গোজের কাছে জমা এবং তার উত্তরের মন্তব্যসমূহ):

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()QT_NO_DEBUG_OUTPUTসংকলন-সময়ে চালু থাকলে বন্ধ করা হয়।

(গোজ একটি মন্তব্যে নোট করেছেন যে নন-কনসোল অ্যাপ্লিকেশানের জন্য এগুলি ভিন্ন স্ট্রমে মুদ্রণ করতে পারে stderr))


দ্রষ্টব্য: Qt মুদ্রণের সমস্ত পদ্ধতি অনুমান করে যে const char*আর্গুমেন্টগুলি ISO-8859-1 এনকোড স্ট্রিংগুলি সমাপ্তি \0অক্ষরগুলির সাথে রয়েছে।


1
QTextStream qStdout() { static QTextStream r{stdout}; return r; }?
ইয়াক্ক - অ্যাডাম নেভ্রামুমন্ট

1
@ ইয়াক্ক ভাল পরামর্শ! আমি আমার উত্তর অন্তর্ভুক্ত করব।
কাইল স্ট্র্যান্ড

কিউফ্যাটাল () কিউটি 5 দিয়ে সংকলন করার সময় একটি ত্রুটি পায়। একটি পোস্ট পড়ুন, এটি যেহেতু (সেখানে থাকুন / কাজ করা) মানসিকতা ছিল না ... এটি ব্যবহার করবেন না! :)
পুনরায় সংযুক্তি

1
@ KyleStrand আপনি কি এর জন্য একটি ফাংশন ব্যবহার করতে পারবেন না? template <typename C> constexpr typename std::remove_const<typename std::remove_reference<C>::type>::type& no_const(C* c) { return const_cast<typename std::remove_const<typename std::remove_reference<C>::type>::type&>(*c); } ব্যবহার করুন: no_const(this).method()। আপনি ক্লাসে একটি পদ্ধতি হিসাবে সেই ফাংশনটি ইনজেক্ট করতে পারেন, এবং তারপরে আপনাকে পাস করার দরকারও পড়বে না this: Foo& no_const() const { return ::no_const(this); } টাইপস নেই, আমি প্রতিশ্রুতি দিচ্ছি।
মনিকা

1
@ মিচ এইচএম, এই লিঙ্কগুলি এবং কিউটি ডকুমেন্টেশনগুলি পর্যালোচনা করে আপনি ঠিক বলেছেন; অস্থায়ী QTextStreamবস্তুগুলির কারণে প্রকৃত জ্ঞাত সমস্যা আছে তা বোঝাতে আমি কিছুই দেখতে পাচ্ছি না । সম্পাদনা করা হয়েছে।
কাইল স্ট্র্যান্ড 16

32

এটি আপনার প্রকল্পের ফাইলে যুক্ত করুন:

CONFIG += console

5
কোন বিল্ড সিস্টেমটি ব্যবহার করা হচ্ছে সে প্রশ্নে কোনও তথ্য দেওয়া হয়নি। এটি ব্যবহার করার সময় কেবল প্রাসঙ্গিক qmake
কাইল স্ট্র্যান্ড

19

আপনি কি ভেরিয়েবল মুদ্রণ করতে চান? আপনি যদি QStrings বলতে চান তবে সেগুলি সি-স্ট্রিংগুলিতে রূপান্তর করা দরকার। চেষ্টা করুন:

std::cout << myString.toAscii().data();

8
@ কোডেরাপুরপা আপনার যুক্ত করতে হবে#include <iostream>
সেবাস্তিয়ান নেগ্রাসজাস

myString.toUtf8().data()আরও ভাল কারণ এটি অ্যাস্কি সীমার বাইরে অক্ষর মুদ্রণ করে। উদাহরণস্বরূপ চীনা অক্ষর
পিটারচাউলা ula

8

এটিতে প্রিন্টফেটের মতো একটি বাক্য গঠন রয়েছে যেমন:

qDebug ("message %d, says: %s",num,str); 

খুব সহজ হিসাবে ভাল



3

সহ সম্পর্কে কি iostream গ্রন্থাগার এবং সুনির্দিষ্ট যে cout হল একটি অবজেক্ট এসটিডি ভালো:

#include <iostream>

std::cout << "Hello" << std::endl;

1

আপনি যদি স্ট্ডিও লাইব্রেরিটি ব্যবহার করে স্ট্যাডারে মুদ্রণ করছেন তবে কল করার fflush(stderr)জন্য বাফারটি ফ্লাশ করা উচিত এবং আপনাকে রিয়েল-টাইম লগিং করা উচিত।



0

ওয়েল, কিউটি তে স্টুডাউটে জিইউআই থেকে প্রাপ্ত বার্তাগুলি কীভাবে আউটপুট করা যায় তা বর্ণনা করার জন্য ইন্টারনেটে বেশ কয়েকটি উদাহরণ অধ্যয়ন করার পরে, আমি qDebug () এর মাধ্যমে এবং qInstallMessageHandler () ইনস্টল করার মাধ্যমে একটি কনসোল-এ বার্তাগুলি পুনঃনির্দেশ করার ক্ষেত্রে একটি স্থায়ী উদাহরণ পরিমার্জন করেছি। কনসোলটি জিইউআইয়ের একই সময়ে প্রদর্শিত হবে এবং প্রয়োজন মনে করা গেলে এটি লুকানো যেতে পারে। কোডটি আপনার প্রকল্পের বিদ্যমান কোডের সাথে একীভূত করা সহজ। এখানে সম্পূর্ণ নমুনা রয়েছে এবং যতক্ষণ আপনি লাইসেন্স জিএনইউ জিপিএল ভি 2 মেনে চলেন ততক্ষণ এটি আপনার পছন্দমতো ব্যবহার করতে নির্দ্বিধায়। আপনাকে কোনও ধরণের ফর্ম এবং একটি মেইন উইন্ডো ব্যবহার করতে হবে বলে আমি মনে করি - অন্যথায় নমুনাটি চলবে, তবে ছাড়তে বাধ্য হলে সম্ভবত ক্রাশ হবে। দ্রষ্টব্য: একটি ঘনিষ্ঠ বোতাম বা মেনু বন্ধের মাধ্যমে ছাড়ার কোনও উপায় নেই কারণ আমি সেই বিকল্পগুলি পরীক্ষা করে দেখেছি এবং অ্যাপ্লিকেশনটি শেষ পর্যন্ত এবং তারপরে ক্রাশ হবে। ক্লোজ বাটন ব্যতীত অ্যাপ্লিকেশন স্থিতিশীল থাকবে এবং আপনি এটিকে মূল উইন্ডো থেকে নিচে বন্ধ করতে পারেন। উপভোগ করুন!

#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();
}

0

"বিল্ড এন্ড রান"> "টার্মিনাল চালান" -> সক্ষম করার জন্য ডিফল্ট

বাফারটি ফ্লাশ করতে এই কমান্ডটি ব্যবহার করুন -> fflush (stdout); আপনি "in n" এ printfবা ব্যবহার করতে পারেন cout

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.