СОК - Создание нового окна
Исходя из создания одностраничных приложений с помощью визуального редактора WYSISWYG в JUCE, у меня возникла небольшая проблема с выяснением того, как вызывать новые окна (за пределами основного окна GUI). Я сделал тестовое приложение, которое просто имеет небольшой минимальный основной графический интерфейс, который я создал с помощью визуального редактора. Имеется кнопка "Создать новое окно". Моя цель состоит в том, чтобы иметь возможность нажать эту кнопку и открыть новое окно, и это новое окно является "компонентом GUI" JUCE (AKA, файл графического / визуального редактора GUI). Теперь я действительно достиг своего рода этого, однако, его ошибок и утверждений, так что было бы здорово получить очень простое, пошаговое руководство.
Я изучил файл main.cpp, который Projucer автоматически создал, чтобы понять, как они создают окно. Вот что я сделал.
1) В моем проекте я добавил новый GUI Component (который становится классом) и назвал его "InvokedWindow". 2) В своем главном заголовке класса компонента GUI я добавил новый указатель области видимости типа InvokedWindow: ScopedPointer<InvokedWindow> invokedWindow;
3) Я создал новую кнопку в главном редакторе графического интерфейса под названием "Создать новое окно" и добавил ее в код обработчика: newWindowPtr = new InvokedWindow;
так что каждый раз, когда нажимается кнопка, создается новый объект типа InvokedWindow.
4) В классе InvokedWindow, в конструкторе, поверх автоматически сгенерированного кода, я добавил:
setUsingNativeTitleBar (true);
setCentrePosition(400, 400);
setVisible (true);
setResizable(false, false);
Что я вроде как получил из основного файла приложения JUCE.
Я также добавил ползунок в это новое окно, просто чтобы добавить к нему функциональность.
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.
*/
Кроме того, я могу закрыть окно один раз и нажать кнопку в главном графическом интерфейсе, чтобы создать еще один экземпляр newWindow, но закрытие его во второй раз приводит к ошибке:
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;
}
};
Это все немного над моей головой. Я подумал, что было бы неплохо создать новое окно с помощью кнопки. Новое окно, которое я мог бы редактировать с помощью графического редактора графического интерфейса, но я не в состоянии полностью разобраться с этим самостоятельно, хотя попробовал. Может ли кто-нибудь опубликовать пошаговое руководство, чтобы сделать это правильно? Я опубликовал это на форумах JUCE, но из-за отсутствия программирования на GUI я не смог понять опубликованные решения (моя собственная вина), поэтому я надеюсь получить очень простое руководство по этому вопросу. Это было бы очень высоко ценится. Спасибо.
1 ответ
Я понял. Мне нужно было создать:
- Новый GUI-компонент (помните, это визуальный редактор в JUCE)
- Класс (я назвал его BasicWindow, основанный на демонстрационном коде JUCE), который действует как оболочка для запуска этого нового окна и содержит компонент GUI.
- 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).cpp файл, который определяет, что такое BasicWindow:
#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 "под его поясом".