Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Hait от Май 11, 2017, 23:39



Название: LNK2019
Отправлено: Hait от Май 11, 2017, 23:39
Добрый вечер. Пытаюсь добавить собственный виджет на форму через design (с помощью promote to от opengl widget). На что ругается линковщик и выдает ошибку:
Код:
mainwindow.obj:-1: error: LNK2019: ссылка на неразрешенный внешний символ "public: __cdecl OGLWidget::OGLWidget(class QWidget *)" (??0OGLWidget@@QEAA@PEAVQWidget@@@Z) в функции "public: void __cdecl Ui_MainWindow::setupUi(class QMainWindow *)" (?setupUi@Ui_MainWindow@@QEAAXPEAVQMainWindow@@@Z)
Код:
#ifndef OGLWIDGET_H
#define OGLWIDGET_H
#include <QOpenGLWidget>

class OGLWidget : public QOpenGLWidget
{
private:
    int layerNumber = 0;
    QColor TransverFunction(short value);
    int clamp(int val, int min, int max);
protected:
    void initializeGL();
    void resizeGL(int width, int height);
    void paintGL();
public:
    OGLWidget(QWidget *parent);
};

#endif // OGLWIDGET_H

Код:
#include "oglwidget.h"
#include "bin.h"


OGLWidget::OGLWidget(QWidget *parent) : QOpenGLWidget(parent)
{

}

int MainWindow::clamp(int val, int min, int max)
{
    return val>max?max:val<min?min:val;
}

void OGLWidget::initializeGL()
{
    glClearColor( 1, 1, 1, 1);
}

QColor OGLWidget::TransverFunction(short value)
{
    int newVal = clamp((value - min) * 255 / (max - min), 0, 255);
    return QColor::fromRgb(newVal, newVal, newVal, 255);
}

void OGLWidget::resizeGL(int width, int height)
{
    glShadeModel(GL_SMOOTH);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, Bin.X, 0, Bin.Y, -1, 1);
    glViewport(0, 0, width, height);
}

void OGLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glBegin(GL_QUADS);
    for (int x_coord = 0; x_coord < Bin.X - 1; x_coord++)
        for (int y_coord = 0; y_coord < Bin.Y - 1; y_coord++)
        {
           
        }
    glEnd();
}

Некоторые функции пока не дописаны. Со стандартным виджетом opengl всё компилируется нормально


Название: Re: LNK2019
Отправлено: PimenS от Май 12, 2017, 01:44
Код:
int MainWindow::clamp(int val, int min, int max)
{
    return val>max?max:val<min?min:val;
}

Не в этом ошибка?


Название: Re: LNK2019
Отправлено: Hait от Май 12, 2017, 08:45
Код:
int MainWindow::clamp(int val, int min, int max)
{
    return val>max?max:val<min?min:val;
}

Не в этом ошибка?

нет:) Данная функция 100% рабочая. Но на всякий случай заменил на return 0. Результата не принесло


Название: Re: LNK2019
Отправлено: gil9red от Май 12, 2017, 09:28
А покажите как выглядит pro-файл


Название: Re: LNK2019
Отправлено: Hait от Май 12, 2017, 09:58
А покажите как выглядит pro-файл
Код:
#-------------------------------------------------
#
# Project created by QtCreator 2017-05-10T00:26:58
#
#-------------------------------------------------
QT       += opengl
QT       += core gui


greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET =tomogram_visualizer
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as 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 \
    bin.cpp \
    oglwidget.cpp

HEADERS  += mainwindow.h \
    bin.h \
    oglwidget.h

FORMS    += mainwindow.ui


Название: Re: LNK2019
Отправлено: __Heaven__ от Май 12, 2017, 10:07
Я бы ещё поглядел на ui_mainwindow.h


Название: Re: LNK2019
Отправлено: Hait от Май 12, 2017, 10:18
Я бы ещё поглядел на ui_mainwindow.h
Код:
#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H

#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QLabel>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QSlider>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QToolBar>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>
#include "oglwidget.h"

QT_BEGIN_NAMESPACE

class Ui_MainWindow
{
public:
    QAction *actionOpen;
    QAction *actionGPU;
    QWidget *centralWidget;
    QGridLayout *gridLayout;
    QVBoxLayout *verticalLayout;
    QSlider *horizontalSlider;
    QSlider *horizontalSlider_2;
    QVBoxLayout *verticalLayout_2;
    QLabel *label;
    QSlider *verticalSlider;
    OGLWidget *openGLWidget;
    QToolBar *mainToolBar;
    QStatusBar *statusBar;

    void setupUi(QMainWindow *MainWindow)
    {
        if (MainWindow->objectName().isEmpty())
            MainWindow->setObjectName(QStringLiteral("MainWindow"));
        MainWindow->resize(666, 479);
        actionOpen = new QAction(MainWindow);
        actionOpen->setObjectName(QStringLiteral("actionOpen"));
        actionGPU = new QAction(MainWindow);
        actionGPU->setObjectName(QStringLiteral("actionGPU"));
        actionGPU->setCheckable(true);
        centralWidget = new QWidget(MainWindow);
        centralWidget->setObjectName(QStringLiteral("centralWidget"));
        gridLayout = new QGridLayout(centralWidget);
        gridLayout->setSpacing(6);
        gridLayout->setContentsMargins(11, 11, 11, 11);
        gridLayout->setObjectName(QStringLiteral("gridLayout"));
        verticalLayout = new QVBoxLayout();
        verticalLayout->setSpacing(6);
        verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
        horizontalSlider = new QSlider(centralWidget);
        horizontalSlider->setObjectName(QStringLiteral("horizontalSlider"));
        horizontalSlider->setOrientation(Qt::Horizontal);

        verticalLayout->addWidget(horizontalSlider);

        horizontalSlider_2 = new QSlider(centralWidget);
        horizontalSlider_2->setObjectName(QStringLiteral("horizontalSlider_2"));
        horizontalSlider_2->setOrientation(Qt::Horizontal);

        verticalLayout->addWidget(horizontalSlider_2);


        gridLayout->addLayout(verticalLayout, 0, 1, 1, 2);

        verticalLayout_2 = new QVBoxLayout();
        verticalLayout_2->setSpacing(6);
        verticalLayout_2->setObjectName(QStringLiteral("verticalLayout_2"));
        label = new QLabel(centralWidget);
        label->setObjectName(QStringLiteral("label"));

        verticalLayout_2->addWidget(label);

        verticalSlider = new QSlider(centralWidget);
        verticalSlider->setObjectName(QStringLiteral("verticalSlider"));
        verticalSlider->setOrientation(Qt::Vertical);

        verticalLayout_2->addWidget(verticalSlider);


        gridLayout->addLayout(verticalLayout_2, 1, 2, 1, 1);

        openGLWidget = new OGLWidget(centralWidget);
        openGLWidget->setObjectName(QStringLiteral("openGLWidget"));

        gridLayout->addWidget(openGLWidget, 1, 1, 1, 1);

        MainWindow->setCentralWidget(centralWidget);
        mainToolBar = new QToolBar(MainWindow);
        mainToolBar->setObjectName(QStringLiteral("mainToolBar"));
        MainWindow->addToolBar(Qt::TopToolBarArea, mainToolBar);
        statusBar = new QStatusBar(MainWindow);
        statusBar->setObjectName(QStringLiteral("statusBar"));
        MainWindow->setStatusBar(statusBar);

        mainToolBar->addAction(actionOpen);
        mainToolBar->addSeparator();
        mainToolBar->addAction(actionGPU);

        retranslateUi(MainWindow);
        QObject::connect(actionOpen, SIGNAL(triggered()), MainWindow, SLOT(OpenFile()));
        QObject::connect(actionGPU, SIGNAL(triggered()), MainWindow, SLOT(UseGPU()));

        QMetaObject::connectSlotsByName(MainWindow);
    } // setupUi

    void retranslateUi(QMainWindow *MainWindow)
    {
        MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", Q_NULLPTR));
        actionOpen->setText(QApplication::translate("MainWindow", "Open", Q_NULLPTR));
        actionOpen->setShortcut(QApplication::translate("MainWindow", "Ctrl+O", Q_NULLPTR));
        actionGPU->setText(QApplication::translate("MainWindow", "GPU", Q_NULLPTR));
        label->setText(QApplication::translate("MainWindow", "TextLabel", Q_NULLPTR));
    } // retranslateUi

};

namespace Ui {
    class MainWindow: public Ui_MainWindow {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_MAINWINDOW_H


Название: Re: LNK2019
Отправлено: gil9red от Май 12, 2017, 10:24
Не уверен, но вроде бы при установке по умолчанию OpenGL модуль не включен


Название: Re: LNK2019
Отправлено: Hait от Май 12, 2017, 10:36
Не уверен, но вроде бы при установке по умолчанию OpenGL модуль не включен
А как это проверить и включить если что?
Да и без включенных модулей разве компилировался бы проект с просто opengl виджетом?


Название: Re: LNK2019
Отправлено: gil9red от Май 12, 2017, 10:50
К предыдущему моему комментарию, я просто пытался угадать, не посмотрев полностью ошибку, сорян

А если просто с OGLWidget работать? Проблем нет с сборкой?


Название: Re: LNK2019
Отправлено: Hait от Май 12, 2017, 10:58
К предыдущему моему комментарию, я просто пытался угадать, не посмотрев полностью ошибку, сорян

А если просто с OGLWidget работать? Проблем нет с сборкой?
Если не пытаться добавить OGLWidget на форму, то всё собирается нормально. Т.е. если я сейчас уберу promote to, то у меня всё нормально соберётся


Название: Re: LNK2019
Отправлено: gil9red от Май 12, 2017, 11:12
Даже не знаю почему не работает, как вариант, OGLWidget добавить вручную в коде в MainWindow черех указатель ui, а не в файле формы

Пока смотрел код меня кое-что смутило...

У вас в одном cpp описываются методы нескольких классов?
Код
C++ (Qt)
#include "oglwidget.h"
#include "bin.h"
 
 
OGLWidget::OGLWidget(QWidget *parent) : QOpenGLWidget(parent)
{
 
}
 
int MainWindow::clamp(int val, int min, int max)
{
   return val>max?max:val<min?min:val;
}
...
 


Название: Re: LNK2019
Отправлено: Hait от Май 12, 2017, 11:24
Даже не знаю почему не работает, как вариант, OGLWidget добавить вручную в коде в MainWindow черех указатель ui, а не в файле формы

Пока смотрел код меня кое-что смутило...

У вас в одном cpp описываются методы нескольких классов?
Код
C++ (Qt)
#include "oglwidget.h"
#include "bin.h"
 
 
OGLWidget::OGLWidget(QWidget *parent) : QOpenGLWidget(parent)
{
 
}
 
int MainWindow::clamp(int val, int min, int max)
{
   return val>max?max:val<min?min:val;
}
...
 

Забыл поправить, когда функцию в этот cpp файл перетаскивал, сейчас всё исправлено.
С ручным добавлением так же не работает

mainwindow
Код:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include "bin.h"
#include <QMainWindow>
#include <QLabel>
#include "oglwidget.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void OpenFile();
    void UseGPU();
private:
    int min = -1000;
    int max = 2000;
    Ui::MainWindow *ui;
    QLabel* currentLevel;
    QLabel* countFPS;
    OGLWidget* ogl;
};

#endif // MAINWINDOW_H

mainwindow.cpp
Код:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtWidgets>
#include <QFileDialog>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->label->setText(QString::number(min));
    ogl = new OGLWidget(this);
    ui->verticalLayout_2->addWidget(ogl, 0);
    currentLevel = new QLabel;
    countFPS = new QLabel;
    ui->statusBar->addWidget(currentLevel, 0);
    currentLevel->setText("Current Level: ");
    ui->statusBar->addWidget(countFPS, 0);
    countFPS->setText("FPS: ");
}

MainWindow::~MainWindow()
{
    delete ui;
}


Название: Re: LNK2019
Отправлено: kambala от Май 12, 2017, 11:31
а если Q_OBJECT дописать в класс?

пробовал полную очистку проекта с удалением Makefile и последующей пересборкой?


Название: Re: LNK2019
Отправлено: Hait от Май 12, 2017, 11:34
а если Q_OBJECT дописать в класс?

пробовал полную очистку проекта с удалением Makefile и последующей пересборкой?
Q_OBJECT дописывал, очистку дебага так же делал. Результатов не принесло


Название: Re: LNK2019
Отправлено: __Heaven__ от Май 12, 2017, 11:34
Код:
int MainWindow::clamp(int val, int min, int max)
{
    return val>max?max:val<min?min:val;
}

Не в этом ошибка?

нет:) Данная функция 100% рабочая. Но на всякий случай заменил на return 0. Результата не принесло
А что она делает в oglwidget.cpp ? Правда, проблема, мне кажется не в ней


Название: Re: LNK2019
Отправлено: __Heaven__ от Май 12, 2017, 11:35
Я ещё предлагаю запустить qmake и пересобрать всё. У меня данный виджет выводится на форму.


Название: Re: LNK2019
Отправлено: kambala от Май 12, 2017, 12:01
а если Q_OBJECT дописать в класс?

пробовал полную очистку проекта с удалением Makefile и последующей пересборкой?
Q_OBJECT дописывал, очистку дебага так же делал. Результатов не принесло
надо не только очистку в креаторе, а еще и руками удалить Makefile в папке сборки (либо всю папку грохнуть) — креатор этого не делает.


Название: Re: LNK2019
Отправлено: Hait от Май 12, 2017, 13:21
Очистил, перезагрузил ПК. Вылезли новые ошибки. Если не отпишусь - значит проблема была в maker.


Название: Re: LNK2019
Отправлено: Hait от Май 12, 2017, 19:23
Проблема в добавлением виджета исчезла, но теперь линковщик начал ругаться на функции opengl
Код:
oglwidget.obj:-1: error: LNK2019: ссылка на неразрешенный внешний символ __imp_glBegin в функции "protected: virtual void __cdecl OGLWidget::paintGL(void)" (?paintGL@OGLWidget@@MEAAXXZ)
oglwidget.obj:-1: error: LNK2019: ссылка на неразрешенный внешний символ __imp_glClear в функции "protected: virtual void __cdecl OGLWidget::paintGL(void)" (?paintGL@OGLWidget@@MEAAXXZ)
ну и т.д.


Название: Re: LNK2019
Отправлено: __Heaven__ от Май 12, 2017, 19:56
opengl необходимо либу подключить в свойствах проекта вроде


Название: Re: LNK2019
Отправлено: Hait от Май 12, 2017, 20:24
opengl необходимо либу подключить в свойствах проекта вроде

Скачал оф пример, там никаких библиотек в хэдере не подключают. Единственно что нашел - двойное наследование от QOpenGLFunctions. Добавил в проект - убрало 3 из 11 ошибок