invalid use of incomlete type 'ui:***'

333
08 августа 2017, 16:31

Нужно сделать базовый класс BaseWidget, который содержит в себе базовый ui и наследоваться от него другими классами, которые будут использовать его ui и, вероятно, дополнять.
Во имя инкапсуляции решил сделать методы для получения указателя на ui.
При использовании его внутри класса BaseWidget проблем не возникает, но при попытке доступа через геттер получаю следующую ошибку:

*/mainwidget.cpp: In constructor ‘MainWidget::MainWidget(QSqlTableModel*, QWidget*)’:
*/mainwidget.cpp:15:17: error: invalid use of incomplete type ‘class Ui::BaseTableWidget’
     connect(ui()->addButton,      &QPushButton::clicked,
                 ^
In file included from */mainwidget.h:5:0,
                 from */mainwidget.cpp:1:
*/basetablewidget.h:12:7: note: forward declaration of ‘class Ui::BaseTableWidget’
 class BaseTableWidget;  
// mainwidget.cpp
MainWidget::MainWidget(QSqlTableModel* m, QWidget *parent) :
    BaseTableWidget(m, headers, parent)
{    
    connect(ui()->addButton,      &QPushButton::clicked,
            this, &MainWidget::addClient);
    ***
}
// basewidget.h
namespace Ui {
class BaseTableWidget;
}
class BaseTableWidget : public QWidget
{
    Q_OBJECT
public:
    explicit BaseTableWidget(QSqlTableModel *model, const QStringList& headers,
                             QWidget *parent = 0);
    virtual ~BaseTableWidget();
    Ui::BaseTableWidget*    ui()                { return _ui; }
    ***
private:
    Ui::BaseTableWidget*    _ui;
    ***
}
#include "basetablewidget.h"
#include "ui_basetablewidget.h"
BaseTableWidget::BaseTableWidget(QSqlTableModel* m, const QStringList &headers,
                                 QWidget *parent) :
    QWidget(parent),
    _ui(new Ui::BaseTableWidget)
{
    _ui->setupUi(this);
    ***
}
Answer 1

Везде где вы используете ui нужно подключать #include "ui_basetablewidget.h". Так как именно там находится его полное объявление. В basewidget.h находится только forward declaration:

namespace Ui {
class BaseTableWidget;
} 

Однако я бы все же посоветовал вам не обращаться к виджетам напрямую через ui. Если вы решите изменить внешний вид BaseTableWidget или отказаться от _ui, то вам придется вносить изменения во всей программе. По сути вы только создаете видимость инкапсуляции, теряя все ее преимущества. Лучше будет сделать методы, которые будут манипулировать _ui:

class MainWindow : public QMainWindow{
public:  
    void setAge(int age){
        _ui->ageInput->setValue(age);
    }
    int age() const{
        return _ui->ageInput->value();
    }
    void setName(const QString &name){
        _ui->nameInput->setText(name);
    }
    QString name() const{
        _ui->nameInput->text();
    }
private:
    Ui::MainWindow *_ui;
};
READ ALSO
Сопрограммы в С++

Сопрограммы в С++

Недавно техническая спецификация сопрограмм, Coroutines TS, дошла до состояния "опубликована"Сопрограммы реализованы в MS VC++ 2017

395
GetModuleFileNameEx - ERROR_PARTIAL_COPY

GetModuleFileNameEx - ERROR_PARTIAL_COPY

GetModuleFileNameEx частенько возвращает 0GetLastError говорит об ошибке 299 (ERROR_PARTIAL_COPY - only part of a ReadProcessMemory or WriteProcessMemory request was completed)

504
В чём может быть проблема?

В чём может быть проблема?

Вот код на C++На этой строчке выдаются такие ошибки:

353
ретрансляция трафика

ретрансляция трафика

Как произвести ретрансляцию трафика через сокеты в Boost AsioПытаюсь реализовать что то вроде сервера, к которому подключаются клиенты с одной...

414