2010-07-29 29 views
41

Tôi có một ứng dụng Qt GUI chạy trên Windows cho phép tùy chọn dòng lệnh được thông qua và trong một số trường hợp tôi muốn đầu ra một thông điệp tới các giao diện điều khiển và sau đó bỏ, ví dụ:Đầu ra của bàn điều khiển trong ứng dụng GUI Qt?

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 

    if (someCommandLineParam) 
    { 
    std::cout << "Hello, world!"; 
    return 0; 
    } 

    MainWindow w; 
    w.show(); 

    return a.exec(); 
} 

Tuy nhiên, thông báo bàn điều khiển không xuất hiện khi tôi chạy ứng dụng từ dấu nhắc lệnh. Có ai biết làm thế nào tôi có thể nhận được điều này để làm việc?

+0

Bạn đang ở trên cửa sổ? Bạn có chắc chắn nó không đưa lên một giao diện điều khiển và sau đó ngay lập tức thoát khỏi nó? Tôi chưa bao giờ thực sự sử dụng Qt ngoài các hướng dẫn cơ bản mặc dù – Falmarri

+0

Tôi đang sử dụng Windows và đang chạy ứng dụng từ dòng lệnh. – Rob

+3

Điều này thực sự khá lạ - Tôi nhận thấy rằng không có đầu ra cho giao diện điều khiển trong chế độ GUI, nhưng nếu bạn chạy chương trình của bạn từ commandline và chuyển hướng nó vào tập tin 'myprogram.exe> ​​output.txt', sau đó đầu ra đất trong này tập tin. Có lẽ một cái gì đó đơn giản như phiên bản cửa sổ của 'mèo' có thể dễ dàng đi xung quanh vấn đề? –

Trả lời

40

Windows không thực sự hỗ trợ các ứng dụng chế độ kép.

Để xem giao diện điều khiển đầu ra bạn cần phải tạo một ứng dụng giao diện điều khiển

CONFIG += console 

Tuy nhiên, nếu bạn kích đúp vào chương trình để bắt đầu phiên bản chế độ GUI sau đó bạn sẽ nhận được một cửa sổ giao diện điều khiển xuất hiện, mà có lẽ không bạn muốn gì. Để ngăn chặn cửa sổ giao diện điều khiển xuất hiện, bạn phải tạo một ứng dụng chế độ GUI trong trường hợp đó bạn sẽ không có đầu ra trong giao diện điều khiển.

Một ý tưởng có thể là tạo ứng dụng nhỏ thứ hai là ứng dụng bảng điều khiển và cung cấp đầu ra. Điều này có thể gọi thứ hai để thực hiện công việc.

Hoặc bạn có thể đặt tất cả các chức năng trong một tệp DLL, sau đó tạo hai phiên bản tệp .exe có chức năng chính rất đơn giản gọi vào DLL. Một là dành cho GUI và một là dành cho giao diện điều khiển.

+0

Vâng, đây là những gì tôi đã nhận ra - hai ứng dụng! – Rob

+0

Có một ứng dụng giao diện điều khiển nhỏ để gọi ứng dụng GUI chính là tốt, nhưng có cách nào để trả lại đầu ra cho ứng dụng bảng điều khiển trong thời gian thực để người dùng có thể xem điều gì đang diễn ra hoặc hiển thị đầu ra điển hình cho những thứ như - h, --version vv? – iforce2d

+3

Bạn có thể giải phóng giao diện điều khiển bằng cách gọi FreeConsole. Vì vậy, ứng dụng của bạn có thể quyết định chế độ nào nó sẽ hoạt động và ẩn bảng điều khiển nếu chạy trong chế độ GUI. –

-2

Trước hết bạn có thể thử đỏ bừng bộ đệm

std::cout << "Hello, world!"<<std::endl; 

Để biết thêm Qt dựa đăng nhập, bạn có thể thử sử dụng qDebug.

+0

qDebug sẽ không hoạt động đối với bản dựng chế độ phát hành. – Rob

+1

std :: endl không thực hiện bất kỳ sự khác biệt BTW. – Rob

2

Tôi đã sử dụng tiêu đề này bên dưới cho các dự án của mình. Hy vọng nó giúp.

#ifndef __DEBUG__H 
#define __DEBUG__H 

#include <QtGui>  

static void myMessageOutput(bool debug, QtMsgType type, const QString & msg) { 

    if (!debug) return; 

    QDateTime dateTime = QDateTime::currentDateTime(); 
    QString dateString = dateTime.toString("yyyy.MM.dd hh:mm:ss:zzz"); 

    switch (type) { 

     case QtDebugMsg: 
      fprintf(stderr, "Debug: %s\n", msg.toAscii().data()); 
      break; 
     case QtWarningMsg: 
      fprintf(stderr, "Warning: %s\n", msg.toAscii().data()); 
      break; 
     case QtCriticalMsg: 
      fprintf(stderr, "Critical: %s\n", msg.toAscii().data()); 
      break; 
     case QtFatalMsg: 
      fprintf(stderr, "Fatal: %s\n", msg.toAscii().data()); 
      abort(); 
    } 
} 

#endif 

PS: bạn có thể thêm dateString vào sản phẩm nếu muốn trong tương lai.

+1

Sử dụng các nhân viên bảo vệ bắt đầu bằng __ * đang yêu cầu sự cố ... – rubenvb

+0

Điều này không liên quan đến câu hỏi ... nhưng có thể bạn đã đúng. – mosg

+0

fprintf không tạo ra bất kỳ đầu ra nào trong các ứng dụng GUI của tôi. – neuviemeporte

0

Trước hết, tại sao bạn cần xuất ra bảng điều khiển trong bản dựng chế độ phát hành? Không ai sẽ nghĩ để tìm ở đó khi có một gui ...

Thứ hai, qDebug là ưa thích :)

Thứ ba, bạn có thể thử thêm console để .pro 's CONFIG của bạn, nó có thể làm việc.

+0

Ứng dụng này có thể chạy ở hai chế độ - bảng điều khiển bằng cách sử dụng công tắc dòng lệnh amd làm GUI. – Rob

+3

Cá nhân giao diện điều khiển là nơi đầu tiên tôi tìm kiếm thông tin lỗi :-) –

0

Trong .pro bạn thêm

CONFIG   += console 
+1

Xin lỗi, trùng lặp với những gì rubenvb đã nói. –

6

Không có cách nào để xuất thông điệp ra bàn điều khiển khi sử dụng QT += gui.

fprintf(stderr, ...) cũng không thể in đầu ra.

Sử dụng QMessageBox để hiển thị thông báo.

+0

QMessageBox có thể xuất ra bàn điều khiển không? o.0 –

4

Ồ, bạn có thể Xuất thông báo khi sử dụng QT += guiCONFIG += console.

Bạn cần printf("foo bar") nhưng cout << "foo bar" không làm việc

+4

Cả printf, cout hoặc qDebug đều không in bất cứ thứ gì trên bàn điều khiển trong cấu hình đó cho tôi. – Zitrax

2

Something bạn có thể muốn điều tra, ít nhất là cho các cửa sổ, là AllocConsole() chức năng trong cửa sổ api. Nó gọi GetStdHandle một vài lần để chuyển hướng stdout, stderr, v.v. (Một thử nghiệm nhanh cho thấy điều này không hoàn toàn làm những gì chúng ta muốn nó làm. Bạn có một cửa sổ console mở cùng với các công cụ Qt khác của bạn, nhưng bạn không thể Có lẽ, bởi vì cửa sổ giao diện điều khiển mở, có một số cách để truy cập nó, xử lý nó, hoặc truy cập và thao tác nó bằng cách nào đó Đây là tài liệu MSDN cho những người quan tâm đến việc tìm ra điều này:

AllocConsole(): http://msdn.microsoft.com/en-us/library/windows/desktop/ms681944%28v=vs.85%29.aspx

GetStdHandle (...): http://msdn.microsoft.com/en-us/library/windows/desktop/ms683231%28v=vs.85%29.aspx

(tôi muốn thêm này như là một lời nhận xét, nhưng các quy tắc ngăn tôi làm như vậy ...)

4
void Console() 
{ 
    AllocConsole(); 
    FILE *pFileCon = NULL; 
    pFileCon = freopen("CONOUT$", "w", stdout); 

    COORD coordInfo; 
    coordInfo.X = 130; 
    coordInfo.Y = 9000; 

    SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coordInfo); 
    SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE),ENABLE_QUICK_EDIT_MODE| ENABLE_EXTENDED_FLAGS); 
} 

int main(int argc, char *argv[]) 
{ 
    Console(); 
    std::cout<<"[email protected]@"; 
    qDebug()<<"start!"; 

Bạn không thể dùng std :: cout như những người khác đã nói, cách của tôi là hoàn hảo ngay cả đối với một số mã không thể bao gồm "qdebug"!

+0

Có vẻ như bạn đang sử dụng pFileCon. Hay tôi hiểu lầm những gì freopen làm? – drescherjm

+0

Bí quyết gọn gàng cho người dùng windows. Bất cứ điều gì nền tảng bạn muốn giới thiệu? –

+0

Giải pháp tuyệt vời. Tôi muốn thêm rằng để có được hành vi giao diện điều khiển Qt bạn cần phải mở rộng mã để bao gồm stderr là tốt. Tôi sử dụng nó để chẩn đoán ứng dụng "Phát hành" được cài đặt trên máy tính của khách hàng. Khi một dòng lệnh cụ thể, ứng dụng Phát hành của tôi sẽ mở ra một giao diện điều khiển. Với stdout và stderr định tuyến lại, giao diện điều khiển sẽ xuất ra tất cả các chẩn đoán của tôi và lỗi của Qt, giống như khi bạn sử dụng 'CONFIG + = console' trong tệp .pro. –

0

Nó có thể là sự giám sát các câu trả lời khác, hoặc có lẽ nó là yêu cầu của người dùng thực sự cần đầu ra console, nhưng câu trả lời rõ ràng cho tôi là tạo một cửa sổ phụ có thể được hiển thị hoặc ẩn (với một hộp kiểm hoặc nút) hiển thị tất cả thư bằng cách nối thêm dòng văn bản vào tiện ích hộp văn bản và sử dụng nó làm bảng điều khiển?

Những lợi ích của một giải pháp đó là:

  • Một giải pháp đơn giản (cung cấp tất cả nó sẽ hiển thị là một khúc gỗ đơn giản).
  • Khả năng gắn tiện ích 'bảng điều khiển' vào cửa sổ ứng dụng chính. (Trong Qt, dù sao đi nữa).
  • Khả năng tạo nhiều bảng điều khiển (nếu có nhiều hơn 1 chuỗi, v.v.).
  • Thay đổi khá dễ dàng từ đầu ra bàn điều khiển cục bộ để gửi nhật ký qua mạng cho khách hàng.

Hy vọng điều này mang đến cho bạn những suy nghĩ, mặc dù tôi chưa có đủ điều kiện để đề cập đến cách bạn nên làm điều này, tôi có thể tưởng tượng nó là điều rất có thể đạt được bởi bất kỳ ai trong chúng ta đọc hiểu!

0

Đảm bảo Qt5Core.dll nằm trong cùng thư mục với ứng dụng của bạn có thể thực thi.

Tôi gặp sự cố tương tự trong Qt5 với ứng dụng bảng điều khiển: nếu tôi khởi động ứng dụng từ Trình tạo Qt, văn bản đầu ra hiển thị, nếu tôi mở cmd.exe và bắt đầu ứng dụng tương tự ở đó, không hiển thị đầu ra . Rất lạ!

Tôi đã giải quyết bằng cách sao chép Qt5Core.dll vào thư mục có ứng dụng chạy được.

Đây là giao diện điều khiển ứng dụng nhỏ của tôi:

#include <QCoreApplication> 
#include <QDebug> 

int main(int argc, char *argv[]) 
{ 
    int x=343; 
    QString str("Hello World"); 
    qDebug()<< str << x<<"lalalaa"; 

    QTextStream out(stdout); 
    out << "aldfjals alsdfajs..."; 
} 
0

Tôi cũng chơi với điều này, phát hiện ra rằng chuyển hướng đầu ra làm việc, nhưng tôi chưa bao giờ thấy đầu ra phía cửa sổ giao diện điều khiển, đó là món quà cho tất cả các cửa sổ ứng dụng.Đây là giải pháp của tôi cho đến nay, cho đến khi tôi tìm thấy một thay thế Qt cho ShowWindow và GetConsoleWindow.

Chạy lệnh này từ dấu nhắc lệnh mà không có tham số - nhận cửa sổ. Chạy từ dấu nhắc lệnh với các tham số (ví dụ: cmd aaa bbb ccc) - bạn nhận được kết quả văn bản trên cửa sổ nhắc lệnh - giống như bạn mong đợi đối với bất kỳ ứng dụng giao diện điều khiển Windows nào.

Xin tha cho ví dụ què - nó đại diện cho khoảng 30 phút mày mò.

#include "mainwindow.h" 
#include <QTextStream> 
#include <QCoreApplication> 
#include <QApplication> 
#include <QWidget> 
#include <windows.h> 

QT_USE_NAMESPACE 

int main(int argc, char *argv[]) 
{ 
    if (argc > 1) { 
     // User has specified command-line arguments 
     QCoreApplication a(argc, argv); 
     QTextStream out(stdout); 
     int  i; 

     ShowWindow (GetConsoleWindow(),SW_NORMAL); 
     for (i=1; i<argc; i++) 
      out << i << ':' << argv [i] << endl; 
     out << endl << "Hello, World" << endl; 
     out << "Application Directory Path:" << a.applicationDirPath() << endl; 
     out << "Application File Path:" << a.applicationFilePath() << endl; 
     MessageBox (0,(LPCWSTR)"Continue?",(LPCWSTR)"Silly Question",MB_YESNO); 
     return 0; 
    } else { 
     QApplication a(argc, argv); 
     MainWindow w; 

     w.setWindowTitle("Simple example"); 
     w.show(); 
     return a.exec(); 
    } 
} 
+0

Không hiệu quả với tôi. Qt-5.6 + CMake –

-1

Sau một cuộc đấu tranh khá dài với chính xác cùng một vấn đề tôi thấy rằng chỉ đơn giản

CONFIG += console 

thực sự làm các trick. Nó sẽ không hoạt động cho đến khi bạn cho QtCreator một cách rõ ràng để thực hiện qmake trên dự án (nhấn chuột phải vào dự án) VÀ thay đổi một cái gì đó bên trong tệp nguồn, sau đó xây dựng lại. Nếu không, trình biên dịch sẽ bị bỏ qua và bạn vẫn không thấy kết quả đầu ra trên dòng lệnh. Bây giờ chương trình của tôi hoạt động ở cả chế độ GUI và chế độ dòng cmd.

6

Add:

#ifdef _WIN32 
if (AttachConsole(ATTACH_PARENT_PROCESS)) { 
    freopen("CONOUT$", "w", stdout); 
    freopen("CONOUT$", "w", stderr); 
} 
#endif 

ở đầu main(). Điều này sẽ cho phép đầu ra cho giao diện điều khiển chỉ khi chương trình được bắt đầu trong một giao diện điều khiển, và sẽ không bật lên một cửa sổ giao diện điều khiển trong các tình huống khác. Nếu bạn muốn tạo một cửa sổ giao diện điều khiển để hiển thị các thông điệp khi bạn chạy ứng dụng bên ngoài một giao diện điều khiển, bạn có thể thay đổi điều kiện để:

if (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole()) 
+0

Điều này không hoạt động cho chuyển hướng (./executable> out.txt) – dvntehn00bz

+1

Tôi đã dành thời gian xem xét điều này và có vẻ như bạn có thể sử dụng GetFileType để xác định xem đường ống có đang hoạt động hay không. Trong mã đã sửa đổi của tôi, tôi đặt stdout_type = GetFileType (GetStdHandle (STD_OUTPUT_HANDLE)); Sau đó, tôi quấn freopen cho stdout với điều kiện: if (stdout_type == FILE_TYPE_UNKNOWN) Điều này có vẻ hiệu quả cho phép quá trình xuất ra một đường ống hiện có nếu có, nhưng đến bàn điều khiển chính khi ống không mở. – dvntehn00bz

+0

Đây là một sửa chữa đơn giản mà làm việc trong trường hợp của tôi trên Win7/Qt 5.10 với một QGuiApplication mà cũng cần đầu ra console. –

-1

Dễ

Bước 1: Tạo dự án mới. Go File-> New File or Project -> Dự án khác -> Dự án trống

Bước 2: Sử dụng mã bên dưới.

Trong file .pro

QT +=widgets 
CONFIG += console 
TARGET = minimal 
SOURCES += \ main.cpp 

Bước 3:Tạo main.cpp và sao chép mã dưới đây.

#include <QApplication> 
#include <QtCore> 

using namespace std; 

QTextStream in(stdin); 
QTextStream out(stdout); 

int main(int argc, char *argv[]){ 
QApplication app(argc,argv); 
qDebug() << "Please enter some text over here: " << endl; 
out.flush(); 
QString input; 
input = in.readLine(); 
out << "The input is " << input << endl; 
return app.exec(); 
} 

Tôi đã tạo các đối tượng cần thiết trong mã để bạn hiểu.

chỉ cần chạy nó

Nếu bạn muốn chương trình của bạn để có được nhiều đầu vào với một số điều kiện. Sau đó, dán mã bên dưới vào Main.cpp

#include <QApplication> 
#include <QtCore> 

using namespace std; 

QTextStream in(stdin); 
QTextStream out(stdout); 

int main(int argc, char *argv[]){ 
    QApplication app(argc,argv); 
    qDebug() << "Please enter some text over here: " << endl; 
    out.flush(); 
    QString input; 
    do{ 
     input = in.readLine(); 
     if(input.size()==6){ 
      out << "The input is " << input << endl; 
     } 
     else 
     { 
      qDebug("Not the exact input man"); 
     } 
    }while(!input.size()==0); 

    qDebug(" WE ARE AT THE END"); 

    // endif 
    return app.exec(); 
} // end main 

Hy vọng nó sẽ giúp bạn.

Good day,

0

Vì vậy, nhiều câu trả lời cho vấn đề này. 0.0

Vì vậy, tôi đã thử nó với Qt5.x từ Win7 đến Win10. Nó đã cho tôi vài giờ để có một giải pháp làm việc tốt mà không tạo ra bất kỳ vấn đề nào đó trong chuỗi:

#include "mainwindow.h" 

#include <QApplication> 

#include <windows.h> 
#include <stdio.h> 
#include <iostream> 

// 
// Add to project file: 
// CONFIG += console 
// 

int main(int argc, char *argv[]) 
{ 
    if(argc < 2) 
    { 
    #if defined(Q_OS_WIN) 
     ::ShowWindow(::GetConsoleWindow(), SW_HIDE); //hide console window 
    #endif 
     QApplication a(argc, argv); 
     MainWindow *w = new MainWindow; 
     w->show(); 
     int e = a.exec(); 
     delete w; //needed to execute deconstructor 
     exit(e); //needed to exit the hidden console 
     return e; 
    } 
    else 
    { 
     QCoreApplication a(argc, argv); 
     std::string g; 
     std::cout << "Enter name: "; 
     std::cin >> g; 
     std::cout << "Name is: " << g << std::endl; 
     exit(0); 
     return a.exec(); 
    } 
} 


tôi đã cố gắng nó cũng mà không các "CONFIG + = ", nhưng sau đó bạn cần phải chuyển hướng các luồng và tạo bảng điều khiển theo cách của riêng bạn:

#ifdef _WIN32 
if (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole()){ 
    freopen("CONOUT$", "w", stdout); 
    freopen("CONOUT$", "w", stderr); 
    freopen("CONIN$", "r", stdin); 
} 
#endif 

BUT điều này chỉ hoạt động nếu bạn bắt đầu nó thông qua một trình gỡ lỗi, nếu không tất cả các đầu vào đều hướng về phía hệ thống. Có nghĩa là, nếu bạn gõ tên thông qua std :: cin hệ thống sẽ cố gắng thực hiện tên như một lệnh. (rất lạ)

Hai cảnh báo khác cho lần thử này là, bạn không thể sử dụng :: FreeConsole() nó sẽ không đóng nó và nếu bạn khởi động nó thông qua bảng điều khiển, ứng dụng sẽ không đóng .



cuối có một Qt help section in QApplication chủ đề này. Tôi cố gắng ví dụ đó với một ứng dụng và nó không làm việc cho GUI, nó stucked ở đâu đó trong một vòng lặp vô tận và GUI sẽ không được trả lại hay nó chỉ đơn giản treo:

QCoreApplication* createApplication(int &argc, char *argv[]) 
{ 
    for (int i = 1; i < argc; ++i) 
     if (!qstrcmp(argv[i], "-no-gui")) 
      return new QCoreApplication(argc, argv); 
    return new QApplication(argc, argv); 
} 

int main(int argc, char* argv[]) 
{ 
    QScopedPointer<QCoreApplication> app(createApplication(argc, argv)); 

    if (qobject_cast<QApplication *>(app.data())) { 
     // start GUI version... 
    } else { 
     // start non-GUI version... 
    } 

    return app->exec(); 
} 


Vì vậy, nếu bạn đang sử dụng Windows và Qt chỉ cần sử dụng tùy chọn bảng điều khiển, hãy ẩn bảng điều khiển nếu bạn cần GUI và đóng nó qua lối ra.

Các vấn đề liên quan