2017-08-04 140 views
1

我爲我的服務器編寫了一個控制檯應用程序。它工作得很好,我可以通過終端啓動它,一切都可以。 對於桌面環境,在程序的settings.ini文件中設置一個標誌以打開MainWindow以顯示正在運行的控制檯應用程序的某些信息將會非常好。後臺的控制檯可以保持打開狀態。我需要的是一個窗口,以及在控制檯運行的主應用程序和MainWindow之間的一些SINGAL/SLOTS。帶可選GUI的Qt控制檯應用程序

如何實現這一點?我想通了,我必須用QApplication和QCoreApplication處理嗎?

+0

如果您想要配置GUI或不使用.ini文件,這意味着您的程序已經能夠同時執行控制檯和GUI,因此它使用QApplication而不是QCoreApplication,它已經將所有GUI代碼編譯並鏈接在一起但不要創建MainWindow。或者你製作了2個不同的二進制文件,你不需要.ini文件,這取決於用戶選擇他想要的程序。在任何情況下,您的程序中始終只有1個QApplication(或QCoreApplication),您不會同時使用兩者。 – ymoreau

回答

0

簡單地說這行到你的親文件:

CONFIG += console 

Qt5.x也從Win7到Win10你可以做這樣的事情

//includes 
#include <QApplication> 
#include <QMainWindow> 
#include <QString> 
#include <QObject> 
#include <QDir> 
#include <QSettings> 

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

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

服務器:

//Here we have the Server class able to send signals 
//Server will be used in main.cpp for console 
//and/or in MainWindow to handle the signals 
class Server : public QObject 
{ 

    Q_OBJECT 

public: 
    Server(QObject *parent = 0) : QObject(parent) 
    { 
     //do server stuff 
     //this->setName("Test"); 
     //std::cout << this->getName() << std::endl; 
     //std::cout << "Enter URL: << std::endl; 
     //std::string url; 
     //std::cin >> url; 
     //_url = QString::fromStdString(url); 
     //emit finished(); 
    } 

signals: 
    void finished(); 

private: 
    QString _url; 

}; 

The Ma inWindow:

//Here is the MainWindow using Server 
class MainWindow : public QMainWindow 
{ 

    Q_OBJECT 

public: 
    MainWindow(QWidget *parent = 0) : QMainWindow() 
    { 
     server = new Server(this); //use server in hybrid mode (console and gui) 
     connect(server, SIGNAL(finished()), this, SLOT(close())); //establish connection 
    } 

private: 
    Server *server; 

}; 

主要:

int main(int argc, char *argv[]) 
{ 
    QString iniPath = QFileInfo(QDir::fromNativeSeparators(argv[0])).absolutePath(); //get the current dir 
    QSettings settings(iniPath+"/settings.ini", QSettings::IniFormat); //open ini 
    bool gui = settings.value("gui", false).toBool(); //read ini 
    if(gui) //decide 
    { 
    #if defined(Q_OS_WIN) 
     // hide console window, but not in your case 
     // ::ShowWindow(::GetConsoleWindow(), SW_HIDE); 
    #endif 
     //std::cout will print to the console in the bg like you wished 
     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); 
     Server *instance = new Server; //use server in console only 
     exit(0); 
     return a.exec(); 
    } 
} 


我試了一下還沒有的 「CONFIG + =控制檯」,但你需要重定向數據流和創建您自己的控制檯:

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

但是這隻有在你通過調試器啓動時纔有效,否則所有的輸入都是針對系統的。意思是,如果你通過std :: cin鍵入一個名字,系統會嘗試執行命令作爲命令。 (非常奇怪)

其他兩個警告這個嘗試是,你不能使用:: FreeConsole()它不會關閉它,如果你通過控制檯啓動它,應用程序將不會關閉。



最後還有一個Qt help section in QApplication這個話題。我試過的例子有一個應用程序,它不會爲GUI工作,它在一個無限循環的地方stucked和GUI不會被渲染或者它只是崩潰:

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


因此,如果您使用的是Windows和Qt,那麼只需使用控制檯選項,如果需要使用GUI並通過退出關閉它,請隱藏控制檯。

相關問題