c++ - mainwindow.cpp:(.text+0x9): 未定义引用,QT 项目在单元测试期间失败
问题描述
我正在提交一个 QT 项目,但是我课程上的自动化单元测试给了我以下错误。我一直试图找出问题所在,但我不知道为什么。完整的错误如下。
/usr/local/bin/moc -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_TESTLIB_LIB -DQT_CORE_LIB -DQT_TESTCASE_BUILDDIR='"/submission-repo/student/12/timer"' --include ./moc_predefs.h -I/usr/local/mkspecs/linux-g++ -I/submission-repo/student/12/timer -I/usr/local/include/QtWidgets -I/usr/local/include/QtGui -I/usr/local/include/QtTest -I/usr/local/include/QtCore -I/usr/include/c++/5 -I/usr/include/x86_64-linux-gnu/c++/5 -I/usr/include/c++/5/backward -I/usr/lib/gcc/x86_64-linux-gnu/5/include -I/usr/local/include -I/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed -I/usr/include/x86_64-linux-gnu -I/usr/include tst_timer.cpp -o tst_timer.moc
g++ -c -pipe -O2 -std=gnu++11 -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_TESTLIB_LIB -DQT_CORE_LIB -DQT_TESTCASE_BUILDDIR='"/submission-repo/student/12/timer"' -I. -isystem /usr/local/include/QtWidgets -isystem /usr/local/include/QtGui -isystem /usr/local/include/QtTest -isystem /usr/local/include/QtCore -I. -isystem /usr/include/libdrm -I. -I/usr/local/mkspecs/linux-g++ -o tst_timer.o tst_timer.cpp
g++ -c -pipe -O2 -std=gnu++11 -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_TESTLIB_LIB -DQT_CORE_LIB -DQT_TESTCASE_BUILDDIR='"/submission-repo/student/12/timer"' -I. -isystem /usr/local/include/QtWidgets -isystem /usr/local/include/QtGui -isystem /usr/local/include/QtTest -isystem /usr/local/include/QtCore -I. -isystem /usr/include/libdrm -I. -I/usr/local/mkspecs/linux-g++ -o mainwindow.o mainwindow.cpp
g++ -c -pipe -O2 -std=gnu++11 -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_TESTLIB_LIB -DQT_CORE_LIB -DQT_TESTCASE_BUILDDIR='"/submission-repo/student/12/timer"' -I. -isystem /usr/local/include/QtWidgets -isystem /usr/local/include/QtGui -isystem /usr/local/include/QtTest -isystem /usr/local/include/QtCore -I. -isystem /usr/include/libdrm -I. -I/usr/local/mkspecs/linux-g++ -o moc_mainwindow.o moc_mainwindow.cpp
g++ -Wl,-O1 -Wl,-rpath,/usr/local/lib -o tst_timer tst_timer.o mainwindow.o moc_mainwindow.o -L/usr/local/lib -lQt5Widgets -lQt5Gui -lQt5Test -lQt5Core -lGL -lpthread
mainwindow.o: In function `MainWindow::on_startButton_clicked()':
mainwindow.cpp:(.text+0x9): undefined reference to `Stopwatch::isRunning()'
mainwindow.o: In function `MainWindow::on_stopButton_clicked()':
mainwindow.cpp:(.text+0x39): undefined reference to `Stopwatch::isRunning()'
mainwindow.o: In function `MainWindow::MainWindow(QWidget*)':
mainwindow.cpp:(.text+0xf7): undefined reference to `Stopwatch::Stopwatch()'
mainwindow.o: In function `MainWindow::update()':
mainwindow.cpp:(.text+0x592): undefined reference to `Stopwatch::isRunning()'
mainwindow.cpp:(.text+0x5c5): undefined reference to `Stopwatch::getTime()'
mainwindow.o: In function `MainWindow::on_startButton_clicked()':
mainwindow.cpp:(.text+0x1e): undefined reference to `Stopwatch::start()'
mainwindow.o: In function `MainWindow::on_stopButton_clicked()':
mainwindow.cpp:(.text+0x4e): undefined reference to `Stopwatch::stop()'
mainwindow.o: In function `MainWindow::on_resetButton_clicked()':
mainwindow.cpp:(.text+0x88): undefined reference to `Stopwatch::reset()'
collect2: error: ld returned 1 exit status
Makefile:245: recipe for target 'tst_timer' failed
make: *** [tst_timer] Error 1
这是我的文件。
mainwindow.hh
#ifndef MAINWINDOW_HH
#define MAINWINDOW_HH
#include <QMainWindow>
#include <QTimer>
#include "stopwatch.hh"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
// Normally this member should be in private part of the
// class, but due to the automated tests it must be more
// accessible.
QTimer* timer;
private slots:
// Add your slots here
void on_startButton_clicked();
void on_stopButton_clicked();
void on_resetButton_clicked();
void update();
signals:
private:
Ui::MainWindow *ui;
Stopwatch* watch;
// Add other necessary members here
};
#endif // MAINWINDOW_HH
stopwatch.hh
#ifndef STOPWATCH_HH
#define STOPWATCH_HH
#include <QAbstractItemModel>
#include <QTime>
class Stopwatch
{
public:
explicit Stopwatch();
void start();
void stop();
void reset();
qint64 getTime();
bool isRunning();
void setRunning(bool running);
private:
bool mRunning;
qint64 mTotalTime;
qint64 mTempTime;
QDateTime mStartTime;
QTime *time;
signals:
public slots:
};
#endif // STOPWATCH_HH
mainwindow.cpp
#include "mainwindow.hh"
#include "ui_mainwindow.h"
#include <QTimer>
#include <QTime>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
watch(new Stopwatch())
{
ui->setupUi(this);
auto lcdpalette = new QPalette;
lcdpalette->setColor(QPalette::Background, QColor(0, 0, 0));
lcdpalette->setColor(QPalette::Base, QColor(255, 160, 122));
lcdpalette->setColor(QPalette::AlternateBase, QColor(255, 160, 122));
ui->lcdNumberMin->setPalette(*lcdpalette);
ui->lcdNumberMin->setAutoFillBackground(true);
ui->lcdNumberSec->setPalette(*lcdpalette);
ui->lcdNumberSec->setAutoFillBackground(true);
QObject::connect(ui->startButton, &QPushButton::clicked,
this, &MainWindow::on_startButton_clicked);
QObject::connect(ui->stopButton, &QPushButton::clicked,
this, &MainWindow::on_stopButton_clicked);
QObject::connect(ui->resetButton, &QPushButton::clicked,
this, &MainWindow::on_resetButton_clicked);
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(1);
}
MainWindow::~MainWindow()
{
delete ui;
delete watch;
}
void MainWindow::on_startButton_clicked()
{
if(not (watch->isRunning()))
{
watch->start();
}
}
void MainWindow::on_stopButton_clicked()
{
if(watch->isRunning())
{
watch->stop();
}
}
void MainWindow::on_resetButton_clicked()
{
ui->lcdNumberMin->display(00);
ui->lcdNumberSec->display(00);
watch->reset();
}
// Triggers every 10 milliseconds (every hundredth of a second)
// Updates the time displayed on the stopwatch.
void MainWindow::update()
{
if(watch->isRunning())
{
qint64 time = watch->getTime();
int hour = time / 1000 / 60 / 60;
int minutes = (time / 1000 / 60) - (hour * 60);
int seconds = (time / 1000) - (minutes * 60);
if(seconds < 10) {
ui->lcdNumberSec->display(QStringLiteral("0%1").arg(seconds));
}
else {
ui->lcdNumberSec->display(QStringLiteral("%1").arg(seconds));
}
if(minutes < 10) {
ui->lcdNumberMin->display(QStringLiteral("0%1").arg(minutes));
}
else {
ui->lcdNumberMin->display(QStringLiteral("%1").arg(minutes));
}
}
}
stopwatch.cpp
#include "stopwatch.hh"
// Default constructor
Stopwatch::Stopwatch() :
mRunning(false),
mTotalTime(0),
mTempTime(0)
{
}
// Starts the stopwatch.
// Instantiates the start time and declares the watch to be running.
void Stopwatch::start()
{
mStartTime = QDateTime::currentDateTime();
mRunning = true;
}
// Pauses the stopwatch.
// Saves the current time and declares the watch to not be running.
void Stopwatch::stop()
{
mTotalTime += mTempTime;
mRunning = false;
}
// Resets the stopwatch.
// Resets the saved time and declares the watch to not be running.
void Stopwatch::reset()
{
mTotalTime = 0;
mRunning = false;
}
// Returns whether the stopwatch is running.
bool Stopwatch::isRunning()
{
return mRunning;
}
// Sets the state of the stopwatch (running/not running)
void Stopwatch::setRunning(bool running)
{
mRunning = running;
}
// Returns the current time of the running stopwatch
qint64 Stopwatch::getTime()
{
mTempTime = mStartTime.msecsTo(QDateTime::currentDateTime());
qint64 time = mTotalTime + mTempTime;
return time;
}
timer.pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = timer
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp \
stopwatch.cpp
HEADERS += \
mainwindow.hh \
stopwatch.hh
FORMS += \
mainwindow.ui
我已经多次清理和重建项目,但没有解决任何问题。
解决方案
推荐阅读
- python - 试图将逗号分隔的文本放入熊猫数据框中
- zoom-sdk - 只需 1 个主持人 ID 同时创建和主持多个 Zoom 会议
- google-maps-urls - 谷歌地图网址,如何将个人姓名添加到目的地?
- javascript - Puppeteer 通过页面重定向获取窗口 URL
- python - SQL Server Native Client 11.0][SQL Server]'»'附近的语法不正确
- android - 无法使用最新的 cmdline-tools cli 运行模拟器
- spring - Junit 测试没有自动连接我的服务类。但它在控制器中工作
- string - 字符串之间的快速标记重叠
- vuetify.js - 为什么在 v-row 和 v-col vuetify 下总是对齐中心
- typo3 - 无法登录到全新 TYPO3 安装的后端