当我为Windows编译我的Qt项目时,我收到以下2个警告:
Makefile.Debug:109: warning: overriding commands for target `debug/moc_mainwindow.cpp'
Makefile.Debug:106: warning: ignoring old commands for target `debug/moc_mainwindow.cpp'
Run Code Online (Sandbox Code Playgroud)
我假设它们表明我的项目配置存在问题,问题是什么以及如何解决?
我首先要提到的是,以下工作正常到Qt 5.0.0 beta 1(也许是beta 2和RC也不知道),但在Qt 5.0.0最终版本中失败了.我只想参考Qt 5.0.0最终版本中看到的结果.所以很可能这与Qt5最近的变化有关.
在C++方面,我在命名空间中有一组类(QObject派生)(可选地用编译器标志触发;类在一个单独的库中,并且库将命名空间的使用作为选项留给用户使用图书馆).这里的一个类Game
可能看起来像这样(摘录):
OAE_BEGIN_NAMESPACE
// forward-declarations:
class Player; // Player is just another class in the same library
class Game : public QObject
{
Q_OBJECT
public:
explicit Game(...);
public slots:
Player *player() const; // <-- the quesion is about such slots
};
OAE_END_NAMESPACE
Run Code Online (Sandbox Code Playgroud)
这些宏OAE_BEGIN/END_NAMESPACE
扩展为namespace OAE_NAMESPACE {
...... }
或者没有,就像Qt所做的那样<qglobal.h>
,只是在宏名称中用"OAE"替换"QT":
#ifndef OAE_NAMESPACE
# define OAE_PREPEND_NAMESPACE(name) ::name
# define OAE_USE_NAMESPACE
# define OAE_BEGIN_NAMESPACE
# define OAE_END_NAMESPACE
# define OAE_BEGIN_INCLUDE_NAMESPACE
# …
Run Code Online (Sandbox Code Playgroud) 我知道它们可以一起使用,但我想知道是否有可能在程序的Qt部分(小部件等)中用Boost.Signal替换Qt的信号和插槽机制.
有人试过吗?任何陷阱?
假设我没有使用任何其他MOC功能并用boost.signal替换信号/插槽,是否可以完全不使用moc?
稍微搞砸了(以及对生成的Makefile的一些编辑),看起来正在发生的是moc没有正确处理MainWindow.h
(包括在内main.cpp
,MainWindow.cpp
除非它与包含它的源文件位于同一文件夹中).
Moc运行MainWindow.cpp
,不处理包含,因此没有看到Q_OBJECT宏,因此继续产生一个空的输出文件.我不确定moc通常是进程包含还是只是扫描目录,但无论哪种方式,需要mocing但在其他目录中的头文件都没有被处理!
问题似乎与moc产生的输出有关.在第一种情况下(编译的那个),hello-world_automoc.cpp
并moc_MainWindow.cpp
生成.hello-world_automoc.cpp
好像
/* This file is autogenerated, do not edit*/
#include "moc_MainWindow.cpp"
Run Code Online (Sandbox Code Playgroud)
在第二种情况下,hello-world_automoc.cpp
产生了一个看起来像的
/* This file is autogenerated, do not edit*/
enum some_compilers { need_more_than_nothing };
Run Code Online (Sandbox Code Playgroud)
并且根本没有moc_MainWindow.cpp
.如果我从cmake手动调用moc而不是在破碎的情况下使用automoc,我确实得到moc_MainWindow.cpp
但它是空的.
首先,不,我没有忘记set(CMAKE_AUTOMOC ON)
.还要注意的是MainWindow
的析构函数声明和实现.
当我的目录结构如下所示:
CMakeLists.txt |__ main.cpp |__ MainWindow.cpp |__ MainWindow.h |__ MainWindow.ui
编译工作得很好.
但是,当它看起来像:
helloworld/ |__ CMakeLists.txt |__ src/ | |__ CMakeLists.txt | …
我有一个Qt小部件C++类,它加载在Qt Creator中创建的ui文件.该类的头文件和源文件位于两个单独的目录中.我无法指示cmake/automoc找到该类的标头.cmake认识到它需要moc C++文件,但它无法找到类似的标题.
有什么我可以帮助cmake找到文件?
如果cpp和头文件都在同一目录中,一切正常.只有在标题位于别处时才会出现此问题.
我的目录结构是
project
src
include
Foo
Bar.h
lib
Foo
Bar.cpp
forms
Bar.ui
Run Code Online (Sandbox Code Playgroud)
在src/include/Foo/Bar.h我有:
// Bar.h
#include <QtWidgets/QWidget>
namespace Ui { class Bar; }
class Bar : public QWidget {
Q_OBJECT
...
}
Run Code Online (Sandbox Code Playgroud)
在src/Foo/Bar.cpp文件中:
#include "Foo/Bar.h"
#include "moc_Bar.cpp"
#include "ui_Bar.h"
Run Code Online (Sandbox Code Playgroud)
我在src/lib/Foo中的CMakeLists.txt设置如下:
# there is a project() call at the root that defines PROJECT_SOURCE_DIR
set(PUBLIC_HEADERS_DIR ${PROJECT_SOURCE_DIR}/src/include)
# Pick up public library headers
include_directories(${PUBLIC_HEADERS_DIR})
# Pick up private headers in library dir
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
# Set up Qt
set(CMAKE_AUTOMOC ON) …
Run Code Online (Sandbox Code Playgroud) 刚刚从Qml中调用重载的C++方法并尝试理解其背后的原因时,遇到了Qt框架的奇怪行为.假设我有一个QList<QVariant>
类似于以下方法的类:
...
Q_SLOT void append(const QVariant &item);
Q_SLOT void append(const QVariantList &items);
Q_SLOT void insert(int index, const QVariant &item);
Q_SLOT void insert(int index, const QVariantList &items);
...
Run Code Online (Sandbox Code Playgroud)
QML:
onclicked: {
var itemCount = myListObject.size();
myListObject.insert(itemCount, "Item " + (itemCount + 1));
}
Run Code Online (Sandbox Code Playgroud)
Qt的某种方式决定将调用void insert(int index, const QVariantList &items)
与过载items
参数设置为一个空的null QVariant
QVariantList
,而不是void insert(int index, const QVariant &item)
具有过载QString
裹QVariant
.
现在,如果我按如下方式更改声明的顺序,它将按预期工作:
Q_SLOT void insert(int index, const QVariantList &items);
Q_SLOT …
Run Code Online (Sandbox Code Playgroud) 为什么在Qt cpp源代码中添加.moc文件的包含很重要?
这是几个Qt样本中常用的步骤,包括这个:http: //doc.qt.io/qt-5/qttestlib-tutorial1-example.html ; #include"testqstring.moc"行应该包含在文件的末尾.
我不明白为什么这是必要的.
谢谢.
我使用qmake && make
以下project.pro
文件编译Qt可执行文件:
INCLUDEPATH *= ../../dependencies/boost
QT *= opengl xml
CONFIG *= qt opengl static
TARGET = myexe
HEADERS = Viewer.hpp MainWindow.hpp Inspector.hpp
SOURCES = main.cpp Viewer.cpp MainWindow.cpp Inspector.cpp
Run Code Online (Sandbox Code Playgroud)
但是,在编译时,moc
会对无法解析的boost宏进行扼流.要解决这个bug,我需要将标志传递-DBOOST_TT_HAS_OPERATOR_HPP_INCLUDED
给moc,但我无法设法这样做.
如何编辑我的.pro
文件以传递给定的标志moc
?(但不是g++
,QMAKE_CXXFLAGS
如此)
我最近需要向类添加一个信号,所以我将类更改为继承自QObject并将Q_OBJECT宏添加到类定义中.由于这样做,我在下面的类别行中得到"vtable for CLICommand'的信号未定义引用错误"错误:
// File clicommand.h
#include <QString>
#include <QStringList>
#include <QTcpSocket>
#include "telnetthread.h"
class CLICommand : public QObject
{
Q_OBJECT
public:
CLICommand(TelnetThread *parentTelnetThread);
signals:
void signal_shutdown_request();
private:
TelnetThread *m_parentTelnetThread;
Run Code Online (Sandbox Code Playgroud)
以及第二个错误"在'vtable for CLICommand''的信号未定义的引用错误"在下面的行上(初始化成员变量):
// File clicommand.cpp
#include <QDebug>
#include <QTcpSocket>
#include <QTextStream>
#include "version.h"
#include "clicommand.h"
#include "telnetthread.h"
#include "logger.h"
CLICommand::CLICommand(TelnetThread *parentTelnetThread)
: m_parentTelnetThread(parentTelnetThread)
{
}
Run Code Online (Sandbox Code Playgroud)
就在这里我发出信号的地方.emit行生成对`CLICommand :: signal_shutdown_request()'的错误未定义引用:
// file shutdown_clicommand.cpp
#include <QIODevice>
#include "clicommand.h"
#include "logger.h"
#include "version.h"
void CLICommand::execute_shutdown(const …
Run Code Online (Sandbox Code Playgroud)