Возникла проблема: не могу собрать проект использующий qt
с помощью cmake
(сам код верный, так как его можно собрать с помощью pro
-file. Мой cmake
-файл:
cmake_minimum_required(VERSION 3.5)
project(calculator)
add_definitions(-Wall -std=c++14)
include_directories(include)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
find_package(Qt5Widgets REQUIRED)
include_directories(Qt5Widgets_INCLUDE_DIRECTORIES)
set(MAIN_SRC sources/main.cpp)
file(GLOB CALC_SRC "sources/calc/*.cpp")
add_executable(${PROJECT_NAME} ${MAIN_SRC} ${CALC_SRC})
qt5_use_modules(${PROJECT_NAME} Widgets)
Код:
//calculator.hpp
#pragma once
#include <QWidget>
#include <QStack>
class QLCDNumber;
class QPushButton;
class Calculator : public QWidget {
Q_OBJECT
private:
QLCDNumber * m_plcd;
QStack<QString> m_stk;
QString m_strDisplay;
public:
Calculator (QWidget * pwgt = 0);
QPushButton * createButton(const QString & str);
void calculate();
public slots:
void slotButtonClicked();
};
//main.cpp
#include <QApplication>
#include "calculator.hpp"
// ----------------------------------------------------------------------
int main(int argc, char** argv)
{
QApplication app(argc, argv);
Calculator calculator;
calculator.setWindowTitle("Calculator");
calculator.resize(230, 200);
calculator.show();
return app.exec();
}
//calculator.cpp
#include <QtWidgets>
#include "calculator.hpp"
Calculator::Calculator(QWidget* pwgt/*= 0*/) : QWidget(pwgt)
{
m_plcd = new QLCDNumber(12);
m_plcd->setSegmentStyle(QLCDNumber::Flat);
m_plcd->setMinimumSize(150, 50);
QChar aButtons[4][4] = {{'7', '8', '9', '/'},
{'4', '5', '6', '*'},
{'1', '2', '3', '-'},
{'0', '.', '=', '+'}
};
//Layout setup
QGridLayout* ptopLayout = new QGridLayout;
ptopLayout->addWidget(m_plcd, 0, 0, 1, 4);
ptopLayout->addWidget(createButton("CE"), 1, 3);
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
ptopLayout->addWidget(createButton(aButtons[i][j]), i + 2, j);
}
}
setLayout(ptopLayout);
}
QPushButton* Calculator::createButton(const QString& str)
{
QPushButton* pcmd = new QPushButton(str);
pcmd->setMinimumSize(40, 40);
connect(pcmd, SIGNAL(clicked()), SLOT(slotButtonClicked()));
return pcmd;
}
void Calculator::calculate()
{
qreal fOperand2 = m_stk.pop().toFloat();
QString strOperation = m_stk.pop();
qreal fOperand1 = m_stk.pop().toFloat();
qreal fResult = 0;
if (strOperation == "+") {
fResult = fOperand1 + fOperand2;
}
if (strOperation == "-") {
fResult = fOperand1 - fOperand2;
}
if (strOperation == "/") {
fResult = fOperand1 / fOperand2;
}
if (strOperation == "*") {
fResult = fOperand1 * fOperand2;
}
m_plcd->display(fResult);
}
void Calculator::slotButtonClicked()
{
QString str = ((QPushButton*)sender())->text();
if (str == "CE") {
m_stk.clear();
m_strDisplay = "";
m_plcd->display("0");
return;
}
if (str.contains(QRegExp("[0-9]"))) {
m_strDisplay += str;
m_plcd->display(m_strDisplay.toDouble());
}
else if (str == ".") {
m_strDisplay += str;
m_plcd->display(m_strDisplay);
}
else {
if (m_stk.count() >= 2) {
m_stk.push(QString().setNum(m_plcd->value()));
calculate();
m_stk.clear();
m_stk.push(QString().setNum(m_plcd->value()));
if (str != "=") {
m_stk.push(str);
}
}
else {
m_stk.push(QString().setNum(m_plcd->value()));
m_stk.push(str);
m_strDisplay = "";
}
}
}
На стадии линковки выдает ошибку:
CMakeFiles/calculator.dir/sources/main.cpp.o: In function `Calculator::~Calculator()':
/home/andrej/Public/example/qt_calculator/sources/main.cpp:(.text._ZN10CalculatorD2Ev[_ZN10CalculatorD2Ev]+0xb): undefined reference to `vtable for Calculator'
CMakeFiles/calculator.dir/sources/calc/Calculator.cpp.o: In function `Calculator::Calculator(QWidget*)':
/home/andrej/Public/example/qt_calculator/sources/calc/Calculator.cpp:(.text+0x58): undefined reference to `vtable for Calculator'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
CMakeFiles/calculator.dir/build.make:123: recipe for target 'calculator' failed
make[2]: *** [calculator] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/calculator.dir/all' failed
make[1]: *** [CMakeFiles/calculator.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
Здесь использованы AUTOUIC
и AUTOMOC
свойства, которые включают функционал CMake для генерации ui
и moc
. Но, чтобы они правильно работали, необходимо в списке файлов исходного кода также иметь файлы заголовков. Это нужно для того, чтобы CMake смог заглянуть в сами файлы и понять нужно ли генерировать для них ui
и moc
шаги компиляции.
Подробнее - в документации.
Функция qt5_use_modules
депрецирована и использовать её не имеет особого смысла в современных версиях Qt. Достаточно target_link_libraries(${PROJECT_NAME} Qt5::Widgets)
. И вызов функции include_directories(Qt5Widgets_INCLUDE_DIRECTORIES)
можно удалить потому, что target_link_libraries
добавит транзитивные зависимости, которые включают пути к файлам заголовков и линковку библиотек.
Проблемы явно не в CMake а где-то ещё:
Я сделал папку, положил туда main.cpp и calculator.cpp/hpp, CMakeLists.txt с Вашего вопроса, открыла в qtcreator, поправил CMakeLists.txt :
set(MAIN_SRC sources/main.cpp)
file(GLOB CALC_SRC "sources/calc/*.cpp")
поменял на
set(MAIN_SRC main.cpp)
file(GLOB CALC_SRC "calc*.cpp")
собрал, запустил - результат записал и прикрепил.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
В приложении имеется view с графиком, поверх которой располагается другая view, потомок SurfaceViewНа SurfaceView предполагается возможность рисования...
У меня возникли проблемы с отправкой JSON на сервер, в логах видна следующая ошибка: W/Systemerr: java
Есть svn сервер в интернетеОткрыл idea, сделал checkout