Qt + CMake + VC ++ создает командную строку - PullRequest
1 голос
/ 04 марта 2012

Я использую комбинацию, упомянутую в заголовке, при попытке запустить пример компоновки окна из учебных пособий 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();
}

И 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})

Сборка и компиляция работают правильно, но когда я запускаю приложение, оно всегда показывает командную строку. Как мне этого избежать?

Ответы [ 4 ]

8 голосов
/ 04 марта 2012

Вы должны указать CMake, что хотите использовать приложение с графическим интерфейсом:

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

Обратите внимание, что при компиляции в 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
6 голосов
/ 29 марта 2012

Я хотел, чтобы сборка релиза скрывала консоль, но все остальные сборки показывали ее.Для этого используйте:

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

Это приведет к появлению следующей ошибки компоновщика: error LNK2019: unresolved external symbol _WinMain@16 referenced in function ___tmainCRTStartup

, чтобы исправить ссылку на QT_QTMAIN_LIBRARY в файле CMakeLists.txt

TARGET_LINK_LIBRARIES(MyApp ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY} ${OTHER_STUFF_TO_LINK})

Теперь вам даже не нужно менять источники, как это было в предыдущем решении.

4 голосов
/ 04 января 2013

В вашем CMakeFile с Qt4 вам не нужно изменять код CPP или добавлять флаги во время компиляции. Просто используйте

set(QT_USE_QTMAIN TRUE)

Он автоматически свяжет qtmain.lib с вашим исполняемым файлом. Эта библиотека определяет другие общие сигнатуры main (), включая WinMain ().

С помощью этого трюка ваше приложение может компилироваться с MSVC под Windows, без использования исходной функции main () и без отображения консоли при запуске приложения вне среды IDE (например, QtCreator).

Окончательный результат CMakeLists.txt может быть:

PROJECT(test)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0)

FIND_PACKAGE(Qt4 REQUIRED)
if(WIN32)
    SET(QT_USE_QTMAIN TRUE)
endif(WIN32)

INCLUDE(${QT_USE_FILE})

SET(test_SRCS main.cc)

QT4_AUTOMOC(${test_SRCS})

ADD_EXECUTABLE(test ${test_SRCS})

TARGET_LINK_LIBRARIES(test ${QT_LIBRARIES})

Кроме того, вам не нужно включать QtCore и QtGui, они включены по умолчанию в QT_USE_FILE (для включаемых папок) и QT_LIBRARIES (для библиотек).

Вам нужно только указать, какие модули вы используете или не используете (для графического интерфейса):

# Use Network and Sql modules
set(QT_USE_QTNETWORK TRUE)
set(QT_USE_QTSQL TRUE)
# Do not use Gui module
set(QT_DONT_USE_QTGUI TRUE)
0 голосов
/ 28 июня 2019

в файле pro, удалите следующее определение консоли, и оно пойдет

CONFIG += console
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...