将子类与Qt一起使用

Using Subclass With Qt

本文关键字:一起 Qt 子类      更新时间:2023-10-16

我想用消息对话框实现一个"退出"应用程序。我将"记事本"定义为Qwidget的一个子类。然后,我定义了一个"退出"方法。

我的代码:

#include <QtWidgets/QApplication>
#include <QTextEdit>
#include <QtGui>
#include <QVBoxLayout>
#include <QMessageBox>
#include <QPushButton>
class Notepad : public QWidget
{
    Q_OBJECT
public:
    Notepad();
    private slots:
    void quit();
private:
    QTextEdit *textEdit;
    QPushButton *quitButton;
};
Notepad::Notepad()
{
    textEdit = new QTextEdit;
    quitButton = new QPushButton(tr("Quit"));
    connect(quitButton, SIGNAL(clicked()), this, SLOT(quit()));
    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(textEdit);
    layout->addWidget(quitButton);
    setLayout(layout);
    setWindowTitle(tr("Notepad"));
}
void Notepad::quit()
{
    QMessageBox messageBox;
    messageBox.setWindowTitle(tr("Notepad"));
    messageBox.setText(tr("Do you really want to quit?"));
    messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
    messageBox.setDefaultButton(QMessageBox::No);
    if (messageBox.exec() == QMessageBox::Yes)
        qApp->quit();
}

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

    Notepad k;
    return a.exec();
}

错误:

1>main.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __cdecl Notepad::metaObject(void)const " (?metaObject@Notepad@@UEBAPEBUQMetaObject@@XZ)
1>main.obj : error LNK2001: unresolved external symbol "public: virtual void * __cdecl Notepad::qt_metacast(char const *)" (?qt_metacast@Notepad@@UEAAPEAXPEBD@Z)
1>main.obj : error LNK2001: unresolved external symbol "public: virtual int __cdecl Notepad::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@Notepad@@UEAAHW4Call@QMetaObject@@HPEAPEAX@Z)
1>main.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const Notepad::staticMetaObject" (?staticMetaObject@Notepad@@2UQMetaObject@@B)

我不明白问题出在哪里。

这只是Qt的奇怪行为。不应该在main.cpp中放置任何类定义。所以只需要单独的代码:

记事本.h

#include <QTextEdit>
#include <QtGui>
#include <QVBoxLayout>
#include <QMessageBox>
#include <QPushButton>
class Notepad : public QWidget
{
    Q_OBJECT
public:
    Notepad();
    private slots:
    void quit();
private:
    QTextEdit *textEdit;
    QPushButton *quitButton;
};

记事本.cpp

#include "Notepad.h"
Notepad::Notepad()
{
    textEdit = new QTextEdit;
    quitButton = new QPushButton(tr("Quit"));
    connect(quitButton, SIGNAL(clicked()), this, SLOT(quit()));
    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(textEdit);
    layout->addWidget(quitButton);
    setLayout(layout);
    setWindowTitle(tr("Notepad"));
}
void Notepad::quit()
{
    QMessageBox messageBox;
    messageBox.setWindowTitle(tr("Notepad"));
    messageBox.setText(tr("Do you really want to quit?"));
    messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
    messageBox.setDefaultButton(QMessageBox::No);
    if (messageBox.exec() == QMessageBox::Yes)
        qApp->quit();
}

和main.cpp

#include <QtWidgets/QApplication>
#include "Notepad.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Notepad k;
    k.show();    //Also you forgot this line. Without this it just invisible app will be
    return a.exec();
}

如果您想使用QObject的Signal Slot机制,您必须在头文件中声明您的类,以允许moc对其进行预处理。