Qt + CMake + VC++产生命令提示符

Sam*_*yon 1 c++ qt qt4 cmake visual-c++

我正在尝试从qt教程运行窗口布局示例时使用标题中提到的组合.主要看起来像这样:

#include <QtGui>

int main(int argc, char **argv) {
  QApplication app(argc, argv);
  QWidget window;
  QLabel *label = new QLabel(QApplication::translate("windowlayout", "Name:"));
  QLineEdit *lineEdit = new QLineEdit();

  QHBoxLayout *layout = new QHBoxLayout();
  layout->addWidget(label);
  layout->addWidget(lineEdit);
  window.setLayout(layout);
  window.setWindowTitle(
      QApplication::translate("windowlayout", "Window layout"));
  window.show();
  return app.exec();
}
Run Code Online (Sandbox Code Playgroud)

和CMakeLists.txt这样:

PROJECT(test)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0)

FIND_PACKAGE(Qt4 REQUIRED)
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR} ${QT_QTCORE_INCLUDE_DIR} ${QT_QTGUI_INCLUDE_DIR})

SET(test_SRCS main.cc)

QT4_AUTOMOC(${test_SRCS})

ADD_EXECUTABLE(test ${test_SRCS})

TARGET_LINK_LIBRARIES(test ${QT_QTGUI_LIBRARIES} ${QT_QTCORE_LIBRARIES})
Run Code Online (Sandbox Code Playgroud)

构建和编译工作正常,但是当我运行应用程序时,它总是显示命令提示符.我该如何避免?

Com*_*sMS 8

你需要告诉CMake你想要一个GUI应用程序:

 # GUI Type
 if(WIN32)
   set(GUI_TYPE WIN32)
 endif(WIN32)
 if(APPLE)
   set(GUI_TYPE MACOSX_BUNDLE)
 endif(APPLE)

 ADD_EXECUTABLE(test ${GUI_TYPE} ${test_SRCS})
Run Code Online (Sandbox Code Playgroud)

请注意,在Windows上进行编译时,这会将程序条目从更改main()WinMain(),因此您还需要修改源.这是我通常做的事情:

#ifdef _WIN32
class Win32CommandLineConverter;

int CALLBACK WinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, LPSTR /* lpCmdLine */, int /* nCmdShow */)
{
    Win32CommandLineConverter cmd_line;
    return main(cmd_line.argc(), cmd_line.argv());
}


class Win32CommandLineConverter {
private:
    std::unique_ptr<char*[]> argv_;
    std::vector<std::unique_ptr<char[]>> storage_;
public:
    Win32CommandLineConverter()
    {
        LPWSTR cmd_line = GetCommandLineW();
        int argc;
        LPWSTR* w_argv = CommandLineToArgvW(cmd_line, &argc);
        argv_ = std::unique_ptr<char*[]>(new char*[argc]);
        storage_.reserve(argc);
        for(int i=0; i<argc; ++i) {
            storage_.push_back(ConvertWArg(w_argv[i]));
            argv_[i] = storage_.back().get();
        }
        LocalFree(w_argv);
    }
    int argc() const
    {
        return static_cast<int>(storage_.size());
    }
    char** argv() const
    {
        return argv_.get();
    }
    static std::unique_ptr<char[]> ConvertWArg(LPWSTR w_arg)
    {
        int size = WideCharToMultiByte(CP_UTF8, 0, w_arg, -1, nullptr, 0, nullptr, nullptr);
        std::unique_ptr<char[]> ret(new char[size]);
        WideCharToMultiByte(CP_UTF8, 0, w_arg, -1, ret.get(), size, nullptr, nullptr);
        return ret;
    }
};
#endif
Run Code Online (Sandbox Code Playgroud)


小智 6

我想要一个发布版本来隐藏控制台,但是所有其他版本都要显示它.要做到这一点:

if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
    SET_TARGET_PROPERTIES(MyApp PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:CONSOLE")
    SET_TARGET_PROPERTIES(MyApp PROPERTIES RELWITHDEBINFO "/SUBSYSTEM:CONSOLE")
    SET_TARGET_PROPERTIES(MyApp PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
    SET_TARGET_PROPERTIES(MyApp PROPERTIES MINSIZEREL "/SUBSYSTEM:WINDOWS")
endif(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
Run Code Online (Sandbox Code Playgroud)

这将引入以下链接器错误: error LNK2019: unresolved external symbol _WinMain@16 referenced in function ___tmainCRTStartup

修复它与CMakeLists.txt文件中的QT_QTMAIN_LIBRARY链接

TARGET_LINK_LIBRARIES(MyApp ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY} ${OTHER_STUFF_TO_LINK})
Run Code Online (Sandbox Code Playgroud)

现在,您甚至不必像以前的解决方案那样更改源代码.