私はQtプログラミングの初心者であり、プログラミングにコードブロックを使用しています。次のように、3つのファイルcommunication.h、commmunicate.cppおよびmain.cppを作成しました。
communicate.h
#ifndef COMMUNICATE_H
#define COMMUNICATE_H
#include <QWidget>
#include <QApplication>
#include <QPushButton>
#include <QLabel>
class Communicate : public QWidget
{
Q_OBJECT
public:
Communicate(QWidget *parent = 0);
private slots:
void OnPlus();
void OnMinus();
private:
QLabel *label;
};
#endif
communicate.cpp
#include "communicate.h"
Communicate::Communicate(QWidget *parent)
: QWidget(parent)
{
QPushButton *plus = new QPushButton("+", this);
plus->setGeometry(50, 40, 75, 30);
QPushButton *minus = new QPushButton("-", this);
minus->setGeometry(50, 100, 75, 30);
label = new QLabel("0", this);
label->setGeometry(190, 80, 20, 30);
connect(plus, SIGNAL(clicked()), this, SLOT(OnPlus()));
connect(minus, SIGNAL(clicked()), this, SLOT(OnMinus()));
}
void Communicate::OnPlus()
{
int val = label->text().toInt();
val++;
label->setText(QString::number(val));
}
void Communicate::OnMinus()
{
int val = label->text().toInt();
val--;
label->setText(QString::number(val));
}
main.cpp
#include "communicate.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Communicate window;
window.setWindowTitle("Communicate");
window.show();
return app.exec();
}
およびその表示エラーは次のとおりです。
obj\Debug\main.o(.text$_ZN11CommunicateD1Ev[Communicate::~Communicate()]+0xb)||In function `ZN7QStringC1EPKc':|
C:\Qt\4.4.3\include\QtCore\..\..\src\corelib\Arch\qatomic_windows.h||undefined reference to `vtable for Communicate'|
obj\Debug\main.o(.text$_ZN11CommunicateD1Ev[Communicate::~Communicate()]+0x17):C:\Qt\4.4.3\include\QtCore\..\..\src\corelib\Arch\qatomic_windows.h||undefined reference to `vtable for Communicate'|
obj\Debug\communicate.o(.text+0x172)||In function `ZN11CommunicateC2EP7QWidget':|
E:\Project\cam2\communicate.cpp|5|undefined reference to `vtable for Communicate'|
obj\Debug\communicate.o(.text+0x17e):E:\Project\cam2\communicate.cpp|5|undefined reference to `vtable for Communicate'|
obj\Debug\communicate.o(.text+0x63a)||In function `ZN11CommunicateC1EP7QWidget':|
E:\Project\cam2\communicate.cpp|5|undefined reference to `vtable for Communicate'|
obj\Debug\communicate.o(.text+0x646):E:\Project\cam2\communicate.cpp|5|more undefined references to `vtable for Communicate' follow|
||=== Build finished: 6 errors, 0 warnings ===|
みんな助けてください...それを理解することはできません...
これは私が前に見た微妙なバグ(そしておそらく少なくとも部分的にはコンパイラのバグ)です。 QWidgetには仮想デストラクタがあるため、コンパイラにはクラスのvtableが必要です。ただし、クラスには仮想関数がないため、Communicateクラス用の仮想関数は作成しませんでした。
virtual ~Communicate() {};
をクラスに追加すると、すべてうまくいきます。
はい、これを理解するのにも時間がかかりました!
問題を解決するための簡単なオプションは、Q_OBJECTマクロを削除するです。これにより、アプリケーションをコンパイルおよびテストできます。が、正しくありませんchoice、CBでQTを毎日使用する場合は、環境を設定する必要があります。
個人的にもっと気に入って、カスタムメイクファイルとファイルを作成する1つのオプション。アプリケーションの「プロ」は、「QtCreator」や「NetBeansIDE」など、他の環境で簡単に移植できます。
従うべき手順を簡単に説明します。 QtCreatorをインストールした場合、QtCreatorファイルによって自己生成されたサポートが必要であり、少しの経験で独自のファイルを作成できます。
この例では、後で「ターゲットリリース」の下でファイルをコンパイルして実行することしかできません。作業環境をカスタマイズする必要があります
####### Compiler, tools and options
PROJECT_NAME = Communicate
QT_INCLUDE = /usr/local/QtSDK/Desktop/Qt/4.8.1/gcc/include/
QT_MKSPECS = /usr/local/QtSDK/Desktop/Qt/4.8.1/gcc/mkspecs/
QT_LIB = /usr/local/QtSDK/Desktop/Qt/4.8.1/gcc/lib
QT_QMAKE = /usr/local/QtSDK/Desktop/Qt/4.8.1/gcc/bin/
CC = gcc
CXX = g++
DEFINES = -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED
CFLAGS = -pipe -O2 -Wall -W -D_REENTRANT $(DEFINES)
CXXFLAGS = -pipe -O2 -Wall -W -D_REENTRANT $(DEFINES)
INCPATH = -I$(QT_MKSPECS)linux-g++ -I../$(PROJECT_NAME) -I$(QT_INCLUDE)QtCore -I$(QT_INCLUDE)QtGui -I/usr/local/QtSDK/Desktop/Qt/4.8.1/gcc/include -I. -I../$(PROJECT_NAME) -I.
LINK = g++
LFLAGS = -Wl,-O1 -Wl,-rpath,$(QT_LIB)
LIBS = $(SUBLIBS) -L$(QT_LIB) -lQtGui -L$(QT_LIB) -L/usr/X11R6/lib -lQtCore -lpthread
AR = ar cqs
RANLIB =
QMAKE = $(QT_QMAKE)qmake
TAR = tar -cf
COMPRESS = gzip -9f
COPY = cp -f
SED = sed
COPY_FILE = $(COPY)
COPY_DIR = $(COPY) -r
STRIP = strip
INSTALL_FILE = install -m 644 -p
INSTALL_DIR = $(COPY_DIR)
INSTALL_PROGRAM = install -m 755 -p
DEL_FILE = rm -f
SYMLINK = ln -f -s
DEL_DIR = rmdir
MOVE = mv -f
CHK_DIR_EXISTS= test -d
MKDIR = mkdir -p
####### Output directory
OBJECTS_DIR = ./Release
####### Files
SOURCES = ../$(PROJECT_NAME)/main.cpp \
../$(PROJECT_NAME)/communicate.cpp moc_communicate.cpp
OBJECTS = main.o \
communicate.o \
moc_communicate.o
DIST = $(QT_MKSPECS)common/unix.conf \
$(QT_MKSPECS)common/linux.conf \
$(QT_MKSPECS)common/gcc-base.conf \
$(QT_MKSPECS)common/gcc-base-unix.conf \
$(QT_MKSPECS)common/g++-base.conf \
$(QT_MKSPECS)common/g++-unix.conf \
$(QT_MKSPECS)qconfig.pri \
$(QT_MKSPECS)modules/qt_webkit_version.pri \
$(QT_MKSPECS)features/qt_functions.prf \
$(QT_MKSPECS)features/qt_config.prf \
$(QT_MKSPECS)features/exclusive_builds.prf \
$(QT_MKSPECS)features/default_pre.prf \
$(QT_MKSPECS)features/release.prf \
$(QT_MKSPECS)features/default_post.prf \
$(QT_MKSPECS)features/unix/gdb_dwarf_index.prf \
$(QT_MKSPECS)features/warn_on.prf \
$(QT_MKSPECS)features/qt.prf \
$(QT_MKSPECS)features/unix/thread.prf \
$(QT_MKSPECS)features/moc.prf \
$(QT_MKSPECS)features/resources.prf \
$(QT_MKSPECS)features/uic.prf \
$(QT_MKSPECS)features/yacc.prf \
$(QT_MKSPECS)features/Lex.prf \
$(QT_MKSPECS)features/include_source_dir.prf \
../$(PROJECT_NAME)/$(PROJECT_NAME).pro
QMAKE_TARGET = $(PROJECT_NAME) Release
DESTDIR = $(OBJECTS_DIR)
TARGET = $(PROJECT_NAME)
first: all
####### Implicit rules
.SUFFIXES: .o .c .cpp .cc .cxx .C
.cpp.o:
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
.cc.o:
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
.cxx.o:
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
.C.o:
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
.c.o:
$(CC) -c $(CFLAGS) $(INCPATH) -o "$@" "$<"
####### Build rules
all: Makefile $(TARGET)
$(TARGET): $(OBJECTS)
$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS)
Makefile: ../$(PROJECT_NAME)/$(PROJECT_NAME).pro $(QT_MKSPECS)linux-g++/qmake.conf $(QT_MKSPECS)common/unix.conf \
$(QT_MKSPECS)common/linux.conf \
$(QT_MKSPECS)common/gcc-base.conf \
$(QT_MKSPECS)common/gcc-base-unix.conf \
$(QT_MKSPECS)common/g++-base.conf \
$(QT_MKSPECS)common/g++-unix.conf \
$(QT_MKSPECS)qconfig.pri \
$(QT_MKSPECS)modules/qt_webkit_version.pri \
$(QT_MKSPECS)features/qt_functions.prf \
$(QT_MKSPECS)features/qt_config.prf \
$(QT_MKSPECS)features/exclusive_builds.prf \
$(QT_MKSPECS)features/default_pre.prf \
$(QT_MKSPECS)features/release.prf \
$(QT_MKSPECS)features/default_post.prf \
$(QT_MKSPECS)features/unix/gdb_dwarf_index.prf \
$(QT_MKSPECS)features/warn_on.prf \
$(QT_MKSPECS)features/qt.prf \
$(QT_MKSPECS)features/unix/thread.prf \
$(QT_MKSPECS)features/moc.prf \
$(QT_MKSPECS)features/resources.prf \
$(QT_MKSPECS)features/uic.prf \
$(QT_MKSPECS)features/yacc.prf \
$(QT_MKSPECS)features/Lex.prf \
$(QT_MKSPECS)features/include_source_dir.prf \
$(QT_LIB)/libQtGui.prl \
$(QT_LIB)/libQtCore.prl
$(QMAKE) -spec $(QT_MKSPECS)linux-g++ -o Makefile ../$(PROJECT_NAME)/$(PROJECT_NAME).pro
$(QT_MKSPECS)common/unix.conf:
$(QT_MKSPECS)common/linux.conf:
$(QT_MKSPECS)common/gcc-base.conf:
$(QT_MKSPECS)common/gcc-base-unix.conf:
$(QT_MKSPECS)common/g++-base.conf:
$(QT_MKSPECS)common/g++-unix.conf:
$(QT_MKSPECS)qconfig.pri:
$(QT_MKSPECS)modules/qt_webkit_version.pri:
$(QT_MKSPECS)features/qt_functions.prf:
$(QT_MKSPECS)features/qt_config.prf:
$(QT_MKSPECS)features/exclusive_builds.prf:
$(QT_MKSPECS)features/default_pre.prf:
$(QT_MKSPECS)features/release.prf:
$(QT_MKSPECS)features/default_post.prf:
$(QT_MKSPECS)features/unix/gdb_dwarf_index.prf:
$(QT_MKSPECS)features/warn_on.prf:
$(QT_MKSPECS)features/qt.prf:
$(QT_MKSPECS)features/unix/thread.prf:
$(QT_MKSPECS)features/moc.prf:
$(QT_MKSPECS)features/resources.prf:
$(QT_MKSPECS)features/uic.prf:
$(QT_MKSPECS)features/yacc.prf:
$(QT_MKSPECS)features/Lex.prf:
$(QT_MKSPECS)features/include_source_dir.prf:
$(QT_LIB)/libQtGui.prl:
$(QT_LIB)/libQtCore.prl:
qmake: FORCE
@$(QMAKE) -spec $(QT_MKSPECS)linux-g++ -o Makefile ../$(PROJECT_NAME)/$(PROJECT_NAME).pro
dist:
@$(CHK_DIR_EXISTS) .tmp/$(PROJECT_NAME)1.0.0 || $(MKDIR) .tmp/$(PROJECT_NAME)1.0.0
$(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/$(PROJECT_NAME)1.0.0/ && $(COPY_FILE) --parents ../$(PROJECT_NAME)/communicate.h .tmp/$(PROJECT_NAME)1.0.0/ && $(COPY_FILE) --parents ../$(PROJECT_NAME)/main.cpp ../$(PROJECT_NAME)/communicate.cpp .tmp/$(PROJECT_NAME)1.0.0/ && (cd `dirname .tmp/$(PROJECT_NAME)1.0.0` && $(TAR) $(PROJECT_NAME)1.0.0.tar $(PROJECT_NAME)1.0.0 && $(COMPRESS) $(PROJECT_NAME)1.0.0.tar) && $(MOVE) `dirname .tmp/$(PROJECT_NAME)1.0.0`/$(PROJECT_NAME)1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/$(PROJECT_NAME)1.0.0
clean:compiler_clean
-$(DEL_FILE) $(OBJECTS)
-$(DEL_FILE) *~ core *.core
####### Sub-libraries
distclean: clean
-$(DEL_FILE) $(TARGET)
#-$(DEL_FILE) Makefile
check: first
mocclean: compiler_moc_header_clean compiler_moc_source_clean
mocables: compiler_moc_header_make_all compiler_moc_source_make_all
compiler_moc_header_make_all: moc_communicate.cpp
compiler_moc_header_clean:
-$(DEL_FILE) moc_communicate.cpp
moc_communicate.cpp: ../$(PROJECT_NAME)/communicate.h
$(QT_QMAKE)moc $(DEFINES) $(INCPATH) ../$(PROJECT_NAME)/communicate.h -o moc_communicate.cpp
compiler_rcc_make_all:
compiler_rcc_clean:
compiler_image_collection_make_all: qmake_image_collection.cpp
compiler_image_collection_clean:
-$(DEL_FILE) qmake_image_collection.cpp
compiler_moc_source_make_all:
compiler_moc_source_clean:
compiler_uic_make_all:
compiler_uic_clean:
compiler_yacc_decl_make_all:
compiler_yacc_decl_clean:
compiler_yacc_impl_make_all:
compiler_yacc_impl_clean:
compiler_Lex_make_all:
compiler_Lex_clean:
compiler_clean: compiler_moc_header_clean
####### Compile
main.o: ../$(PROJECT_NAME)/main.cpp ../$(PROJECT_NAME)/communicate.h
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o main.o ../$(PROJECT_NAME)/main.cpp
communicate.o: ../$(PROJECT_NAME)/communicate.cpp ../$(PROJECT_NAME)/communicate.h
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o communicate.o ../$(PROJECT_NAME)/communicate.cpp
moc_communicate.o: moc_communicate.cpp
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_communicate.o moc_communicate.cpp
####### Install
install: FORCE
uninstall: FORCE
FORCE:
QT += core gui
TARGET = Communicate
TEMPLATE = app
SOURCES += main.cpp\
communicate.cpp
HEADERS += communicate.h
CBはwxWidgetsおよびC/C++を操作するための最適な環境ですが、個人的にはQtを操作する場合、QtCreatorはよりネイティブで最適化された開発環境を提供すると思いますプロジェクトQTで作業する
MOC(meta object compiler)は、その通信を行うために、communicate.h(および他のQ_OBJECTで処理されたクラス)を知る必要があります。それらをHEADERSセクションの下の.proファイルに配置しない限り、この「未定義の参照」を取得します
デストラクタを定義する必要があります。 QObjectから派生している場合でも、コンパイラがデフォルトのコンストラクタ/デストラクタを使用するだけでは不十分です。