19

このリンクからの次の例:http://developer.kde.org/documentation/books/kde-2.0-development/ch03lev1sec3.html

#include <QObject>
#include <QPushButton>
#include <iostream>
using namespace std;

class MyWindow : public QWidget
{
    Q_OBJECT  // Enable slots and signals
    public:
        MyWindow();
    private slots:
        void slotButton1();
        void slotButton2();
        void slotButtons();
    private:
        QPushButton *button1;
        QPushButton *button2;
};

MyWindow :: MyWindow() : QWidget()
{
    // Create button1 and connect button1->clicked() to this->slotButton1()
    button1 = new QPushButton("Button1", this);
    button1->setGeometry(10,10,100,40);
    button1->show();
    connect(button1, SIGNAL(clicked()), this, SLOT(slotButton1()));

    // Create button2 and connect button2->clicked() to this->slotButton2()
    button2 = new QPushButton("Button2", this);
    button2->setGeometry(110,10,100,40);
    button2->show();
    connect(button2, SIGNAL(clicked()), this, SLOT(slotButton2()));

    // When any button is clicked, call this->slotButtons()
    connect(button1, SIGNAL(clicked()), this, SLOT(slotButtons()));
    connect(button2, SIGNAL(clicked()), this, SLOT(slotButtons()));
}

// This slot is called when button1 is clicked.
void MyWindow::slotButton1()
{
    cout << "Button1 was clicked" << endl;
}

// This slot is called when button2 is clicked
void MyWindow::slotButton2()
{
    cout << "Button2 was clicked" << endl;
}

// This slot is called when any of the buttons were clicked
void MyWindow::slotButtons()
{
    cout << "A button was clicked" << endl;
}

int main ()
{
    MyWindow a;
}

結果:

    [13:14:34 Mon May 02] ~/junkPrograms/src/nonsense  $make
g++ -c -m64 -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/opt/qtsdk-2010.05/qt/mkspecs/linux-g++-64 -I. -I/opt/qtsdk-2010.05/qt/include/QtCore -I/opt/qtsdk-2010.05/qt/include/QtGui -I/opt/qtsdk-2010.05/qt/include -I. -I. -o signalsSlots.o signalsSlots.cpp
g++ -m64 -Wl,-O1 -Wl,-rpath,/opt/qtsdk-2010.05/qt/lib -o nonsense signalsSlots.o    -L/opt/qtsdk-2010.05/qt/lib -lQtGui -L/opt/qtsdk-2010.05/qt/lib -L/usr/X11R6/lib64 -lQtCore -lpthread
signalsSlots.o: In function `MyWindow::MyWindow()':
signalsSlots.cpp:(.text+0x1a2): undefined reference to `vtable for MyWindow'
signalsSlots.cpp:(.text+0x1aa): undefined reference to `vtable for MyWindow'
signalsSlots.o: In function `MyWindow::MyWindow()':
signalsSlots.cpp:(.text+0x3e2): undefined reference to `vtable for MyWindow'
signalsSlots.cpp:(.text+0x3ea): undefined reference to `vtable for MyWindow'
signalsSlots.o: In function `main':
signalsSlots.cpp:(.text+0x614): undefined reference to `vtable for MyWindow'
signalsSlots.o:signalsSlots.cpp:(.text+0x61d): more undefined references to `vtable for MyWindow' follow
collect2: ld returned 1 exit status
make: *** [nonsense] Error 1

vtableは仮想関数用です、AFAIK、ここでのエラーの理由は何ですか?

4

5 に答える 5

36

ファイルQObjectで宣言しているため、mocはコードを生成しないようです。.cppこれを修正する最も簡単な方法は、の宣言をヘッダーに移動し、 .proファイルのリストにMyWindowヘッダーを追加することです。HEADERS

HEADERS += yourheader.h 

その後、再実行しqmakeます。

(あなたが見ているKDE 2.0の本は非常に時代遅れであることに注意してください)

于 2011-05-02T08:14:55.813 に答える
23

遅すぎるかもしれませんが...同じ問題があり、それがどこから来ているのかを見つけるためにしばらく戦いました。

プロジェクトを右クリックし、「Run qmake」を選択して、MOCクラスの新しいビルドを実行します。通常は自動的に実行されます...

mocコンパイラは、moc_xxxx.cppでスタブと呼び出しを生成し、vtableのものを生成します

于 2012-12-29T21:35:40.593 に答える
1

Main()を次のように変更するだけです。

#include <QtGui/QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyWindow w;

    w.show();

    return a.exec();
}
于 2011-05-02T08:16:34.673 に答える
1

上記のandrefコメントに基づいて、すべてがのような1つのcppファイルにあるstuff.cpp場合は、ファイルの最後に次のように追加する必要があります。

#include "moc_stuff.cpp"

(これはQt 4.7.0の場合です)

于 2012-06-04T16:51:55.027 に答える
0

この問題は、次の理由のいくつかが原因である可能性があります。私は時々それらすべてに出くわしました。


クラスヘッダーにQ_OBJECTマクロがない可能性があります。他の回答ですでに指摘されているように、マクロをヘッダーに追加します。

class MyWidg : public QWidget
{
    Q_OBJECT

クラスヘッダーはmocによって解析されない場合があります。.pro(または.pri)プロジェクトファイルのHEADERS定義にヘッダーファイルを追加します。

HEADERS += file.h

上記のいずれにも当てはまらない場合は、qmakeの実行後にQ_OBJECTマクロがヘッダーに追加された場合に備えて、mocがヘッダーを再度解析するようにqmakeを再度実行する必要があります。もう一度qmakeを実行してください。

于 2018-03-06T12:38:03.533 に答える