【问题标题】:Connecting Signals and Slots between Child and Parent (invalid use of incomplete type)连接 Child 和 Parent 之间的 Signals 和 Slots(不完整类型的无效使用)
【发布时间】:2017-11-26 02:24:25
【问题描述】:

我正在尝试将来自子窗口(@98​​7654321@ 名为 VolumePage)的信号连接到其父窗口(@98​​7654323@ 名为 MockUI)。我遇到了一个:

不完整类型'class Ui::VolumePage'的无效使用

尝试建立连接时出错。

当我制作音量页面时,我正在尝试在 MockUI.cpp 内部进行连接。 (在按下按钮时发生)

 void MockUI::on_pushButton_3_clicked()
 {
 //Non-Modal Approach

 volPage = new VolumePage(this); 
 volPage->show();
 connect(volPage->ui->verticalSlider,SIGNAL(valueChanged(int)),ui->progressBar,SLOT(setValue(int)));
 }

我已公开Ui::VolumePage *ui;

这是整个错误:

错误:无效使用不完整类型 'class Ui::VolumePage' connect(volPage->ui->verticalSlider,SIGNAL(valueChanged(int)),ui->progressBar,SLOT(setValue(int)));

谁能帮我理解问题出在哪里,或者用另一种干净的方式来做我想做的事情?

编辑:(其他来源)

VolumePage.h:

#ifndef VOLUMEPAGE_H
#define VOLUMEPAGE_H

#include <QDialog>

namespace Ui {
class VolumePage;
}

class VolumePage : public QDialog
{
    Q_OBJECT

public:
    explicit VolumePage(QWidget *parent = 0);
    Ui::VolumePage *ui;
    ~VolumePage();

private slots:
    void on_verticalSlider_valueChanged(int value);

private:

};

#endif // VOLUMEPAGE_H

mockUI.cpp:

#include "mockUI.h"
#include "ui_mock_ics.h"
#include <QLCDNumber>
#include "volumepage.h"

MockUI::MockUI(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MockUI)
{
    ui->setupUi(this);

}

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


void MockUI::on_pushButton_3_clicked()
{
    //Modal Approach
    //VolumePage volPage;
    //volPage.setModal(true);
    //volPage.exec();

    //Non-Modal Approach
    volPage = new VolumePage(this);    
    volPage->show();
    connect(volPage->ui->verticalSlider,SIGNAL(valueChanged(int)),ui->progressBar,SLOT(setValue(int)));

}

volumepage.cpp:

#include "volumepage.h"
#include "mockUI.h"
#include "ui_volumepage.h"

VolumePage::VolumePage(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::VolumePage)
{
    ui->setupUi(this);
    setWindowFlags(Qt::FramelessWindowHint | Qt::Popup);
    //Mock_ICS* ics = (Mock_ICS*)parent;
    //connect(ui->verticalSlider,SIGNAL(valueChanged(int)),ics->ui->progressBar,SLOT(setValue(int)));
    //connect(ui->verticalSlider,SIGNAL(valueChanged(int)),this->parent()->progressBar,SLOT(setValue(int)));


}

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

【问题讨论】:

    标签: qt


    【解决方案1】:

    Ui::VolumePage *ui 应保持私密。而是在 volPage 上创建一个信号,例如 verticalSliderValueChanged(int value)。见下文...

    mockui.h

    #ifndef MOCKUI_H
    #define MOCKUI_H
    
    #include <QMainWindow>
    #include "volumepage.h"
    
    namespace Ui {
    class MockUI;
    }
    
    class MockUI : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MockUI(QWidget *parent = 0);
        ~MockUI();
        VolumePage* volPage;
    
    private slots:
        void on_pushButton_3_clicked();
    
    private:
        Ui::MockUI *ui;
    };
    
    #endif // MOCKUI_H
    

    mockui.cpp

    #include "mockui.h"
    #include "ui_mockui.h"
    #include "volumepage.h"
    
    MockUI::MockUI(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MockUI)
    {
        ui->setupUi(this);
    }
    
    MockUI::~MockUI()
    {
        delete ui;
    }
    
    
    void MockUI::on_pushButton_3_clicked()
    {
        //Non-Modal Approach
        volPage = new VolumePage(this);
        volPage->show();
        connect(volPage,SIGNAL(verticalSliderValueChanged(int)),ui->progressBar,SLOT(setValue(int)));
    
    }
    

    volumepage.h

    #ifndef VOLUMEPAGE_H
    #define VOLUMEPAGE_H
    
    #include <QDialog>
    
    namespace Ui {
    class VolumePage;
    }
    
    class VolumePage : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit VolumePage(QWidget *parent = 0);
        ~VolumePage();
    
    signals:
        void verticalSliderValueChanged(int value);
    
    private slots:
        void on_verticalSlider_valueChanged(int value);
    
    private:
        Ui::VolumePage *ui;
    };
    
    #endif // VOLUMEPAGE_H
    

    volumepage.cpp

    #include "volumepage.h"
    #include "ui_volumepage.h"
    
    VolumePage::VolumePage(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::VolumePage)
    {
        ui->setupUi(this);
    }
    
    VolumePage::~VolumePage()
    {
        delete ui;
    }
    
    void VolumePage::on_verticalSlider_valueChanged(int value)
    {
        emit verticalSliderValueChanged(value);
    }
    

    【讨论】:

    • 非常感谢您的回答。似乎还有其他方法可以做到这一点 - 但这个答案看起来像是最干净的方法来调整 Qt Creator 自动生成的内容来做我想做的事情。
    【解决方案2】:

    这是 C++ 中pImpl idiom 的示例。 VolumePage 类是你应该使用的——这是 Qt Creator 生成的“公共”接口。 Ui::VolumePage 包含您不必担心的复杂细节。

    因此,在您的代码中,您应该使用VolumePage,而不是Ui::VolumePage。你不应该公开Ui::VolumePage

    【讨论】:

    • #include "volumepage.h" 在 mockUI.cpp 的开头 - 我还需要做些什么吗?
    • @josh.spickes 也许您还缺少项目文件中包含的widgets 模块?
    • 显示 volumepage.h 和 mockUI.cpp 的相关部分 - 问题似乎就在那里。从您所说的来看,它们不包含您尝试连接的类型的完整定义。
    • @BartoszKP 添加了源代码。希望这更清楚。
    • 90% 的代码是由 Qt Creator 自动生成的。我认识到,当 Ui::VolumePage 和 VolumePage 是完全不同的东西时,它们共享相同的名称是很奇怪的。这正是 Qt Creator 使用默认设置吐出的内容。我认为在 'ui->setupUi(this);' 中有一些工作要做。打电话说我不明白。它必须填充该调用中的 UI 元素。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-05
    • 1970-01-01
    • 1970-01-01
    • 2017-10-24
    • 2010-10-13
    • 1970-01-01
    相关资源
    最近更新 更多