我正在尝试从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})
构建和编译工作正常,但是当我运行应用程序时,它总是显示命令提示符。我该如何避免?
答案 0 :(得分: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})
请注意,在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
答案 1 :(得分: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")
这将引入以下链接器错误:
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})
现在您甚至不必像以前的解决方案那样更改您的来源。
答案 2 :(得分:4)
在使用Qt4的CMakeFile中,您无需在编译时更改CPP代码或添加标记。只需使用
set(QT_USE_QTMAIN TRUE)
它会自动将qtmain.lib与您的可执行文件链接。该库定义了其他常见的main()签名,包括WinMain()。
通过这个技巧,您的应用程序可以在Windows下使用MSVC进行编译,而无需在您的IDE(例如QtCreator)之外运行应用程序时隐藏原始的main()函数并且不显示控制台。
最终生成的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(用于库)中。
您只需要设置您使用的模块,或者您不使用(对于Gui):
# 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)
答案 3 :(得分:-1)
在pro文件中,删除以下控制台定义,它将消失
CONFIG += console