c++ - JUCE - 制作一个新窗口

标签 c++ juce

从使用 JUCE 中的可视化所见即所得编辑器制作单页应用程序开始,我在弄清楚如何调用新窗口(在主 GUI 窗口之外)时遇到了一些麻烦。我制作了一个测试应用程序,它只有一个我用可视化编辑器创建的最小主 GUI。它有一个按钮“制作新窗口”。我的目标是能够单击该按钮并弹出一个新窗口,并且这个新窗口是 JUCE“GUI 组件”(又名图形/可视化 GUI 编辑器文件)。现在,我实际上有点实现了这一点,但是,它会抛出错误和断言,所以如果能获得一个非常简单的分步教程会很棒。

我研究了 Projucer 自动创建的 main.cpp 文件,以了解他们是如何创建窗口的。这是我所做的。

1) 在我的项目中,我添加了一个新的 GUI 组件(成为一个类)并将其命名为“InvokedWindow”。 2) 在我的主要 GUI 组件类 header 中,我添加了一个新的 InvokedWindow 类型的作用域指针:ScopedPointer<InvokedWindow> invokedWindow; 3) 我在主 GUI 编辑器中创建了一个名为“制作新窗口”的新按钮,并将其添加到处理程序代码中: newWindowPtr = new InvokedWindow;这样只要按下按钮,就会创建一个 InvokedWindow 类型的新对象。 4) 在 InvokedWindow 类的构造函数中,在自动生成的代码之上,我添加了:

setUsingNativeTitleBar (true);
setCentrePosition(400, 400);
setVisible (true);
setResizable(false, false);

这是我从 JUCE 应用程序的主文件中得到的。

我还向这个新窗口添加了一个 slider ,只是为了为其添加功能。

5) 我添加了一个重载函数来让我关闭窗口:

void InvokedWindow::closeButtonPressed()
{
    delete this;
}

所以,现在当我运行应用程序并单击创建新窗口按钮时,一个新窗口会弹出,但我得到一个断言:

/* Agh! You shouldn't add components directly to a ResizableWindow - this class
   manages its child components automatically, and if you add your own it'll cause
   trouble. Instead, use setContentComponent() to give it a component which
   will be automatically resized and kept in the right place - then you can add
   subcomponents to the content comp. See the notes for the ResizableWindow class
   for more info.

   If you really know what you're doing and want to avoid this assertion, just call
   Component::addAndMakeVisible directly.
*/

此外,我可以关闭一次窗口并点击主 GUI 中的按钮以创建新窗口的另一个实例,但第二次关闭它会导致错误:

template <typename ObjectType>
struct ContainerDeletePolicy
{
    static void destroy (ObjectType* object)
    {
        // If the line below triggers a compiler error, it means that you are using
        // an incomplete type for ObjectType (for example, a type that is declared
        // but not defined). This is a problem because then the following delete is
        // undefined behaviour. The purpose of the sizeof is to capture this situation.
        // If this was caused by a ScopedPointer to a forward-declared type, move the
        // implementation of all methods trying to use the ScopedPointer (e.g. the destructor
        // of the class owning it) into cpp files where they can see to the definition
        // of ObjectType. This should fix the error.
        ignoreUnused (sizeof (ObjectType));

        delete object;
    }
};

这让我有点头疼。我在想通过一个按钮创建一个新窗口并不会太糟糕。我可以使用图形 GUI 编辑器编辑的新窗口,但我自己无法完全弄清楚,尽管我确实尝试过。任何人都可以发布以正确方式执行此操作的分步指南吗?我确实在 JUCE 论坛上发布了这个,但是由于我缺乏 GUI 编程,我无法理解发布的解决方案(我自己的错),所以我希望得到一个非常简单的指南。将不胜感激。谢谢。

最佳答案

我想通了。我需要创建:

  1. 一个新的 GUI 组件(记住,这是 JUCE 中的可视化编辑器)
  2. 一个类(我将其称为 BasicWindow,基于 JUCE 演示代码)充当运行此新窗口并包含 GUI 组件的外壳。
  3. 一个 JUCE SafePointer,它在单击按钮时生成 BasicWindow 类型的新对象并将属性设置到该窗口。

这是我的代码:

引用第 3 行在按钮的处理程序部分内创建新窗口:

basicWindow = new BasicWindow("Information", Colours::grey, DocumentWindow::allButtons);

basicWindow->setUsingNativeTitleBar(true);
basicWindow->setContentOwned(new InformationComponent(), true);// InformationComponent is my GUI editor component (the visual editor of JUCE)

basicWindow->centreWithSize(basicWindow->getWidth(), basicWindow->getHeight());
basicWindow->setVisible(true);

引用第 2 行)定义 BasicWindow 是什么的 .cpp 文件:

#include "../JuceLibraryCode/JuceHeader.h"

class BasicWindow : public DocumentWindow
{
private:
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BasicWindow)

public:
    BasicWindow (const String& name, Colour backgroundColour, int buttonsNeeded)
    : DocumentWindow (name, backgroundColour, buttonsNeeded)
    {
    }

    void closeButtonPressed() override
    {
        delete this;
    }
};

并引用第 1 行)制作 GUI 编辑器组件,这很容易做到。您只需在 JUCE 文件管理器中添加一个新文件即可。 “添加新的 GUI 组件”,然后直观地添加所有元素和处理程序代码。

我最大的问题是我使用的是 JUCE ScopedPointer,所以在删除对象后,指向它的指针没有被设置回 NULL。 SafePointer 就是这样做的。如果需要任何更多解释,我很乐意提供帮助,因为这对于“在他的腰带下”没有太多 GUI 开发的人来说太糟糕了。

关于c++ - JUCE - 制作一个新窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43771969/

相关文章:

c++ - 参数引用有物理变量吗?

c++ - 使用模板的条件函数调用

c++ - C 和 C++ 中的宏重新定义

c++ - 创建一个继承自另一个类的类?

ios - JUCE iOS 构建没有目标

c++ - 我的矩阵乘法代码什么都不做(C++)

c++:static_cast<int> std::sqrt(x) 是否总是为平方的正整数给出准确的结果?

c++ - 没有嵌入文件的 JUCE 图像按钮

c++ - VST 音频输入值与 Matlab 中完全不同

c++ - 如何使用 Juce 加载脉冲响应的音频文件