gpt4 book ai didi

c++ - 带有 AUI : OpenGL render loop method and wxPaintEvent 的 wxWidgets

转载 作者:太空宇宙 更新时间:2023-11-04 13:32:49 30 4
gpt4 key购买 nike

我传统上使用 wxWidgets 绘制到 OpenGL Canvas 的方法是从当前 OpenGL Canvas 触发 30 赫兹定时刷新(),然后生成一个“wxEVT_PAINT”,我可以将其传播到其余部分框架。我还绑定(bind)到 wxEVT_PAINT 并调用 refresh() 来捕获任何帧大小调整。

在我没有使用 wxWidgets AUI 的程序中,这个方法完美无缺。

但是,如果我尝试使用 AUI,每次我尝试绑定(bind)到 wxEVT_PAINT 时,我的绘制事件都不会触发。有时绑定(bind)到绘画事件甚至会阻止其他事件(如计时器)的触发。

AUI 是否有一些特殊的方式来处理事件,或者我在这里缺少的 wxEVT_PAINT?在 AUI 托管框架内绘制到 OpenGL 窗口的最佳方法是什么?任何人都可以提供提示或示例,因为关于 AUI 的这个主题似乎不存在文档。

编辑:为了清楚起见,我在下面添加了我的源代码,供任何想帮助查找问题的人使用。我已经删除了 OpenGL 部分,因为我实际上只是想让 wxEVT_PAINT 在我调整窗口大小时触发框架中的绑定(bind)处理程序。

GeneratedFrame.h

#ifndef __GENERATEDFRAME_H__
#define __GENERATEDFRAME_H__

#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/panel.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/string.h>
#include <wx/menu.h>
#include <wx/frame.h>
#include <wx/aui/aui.h>


class MainFrame : public wxFrame
{
private:

protected:
wxPanel* m_panelMainView;
wxMenuBar* m_menubar2;

public:

MainFrame( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("SimpleAui"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 646,516 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
wxAuiManager m_mgr;

~MainFrame();

};

#endif //__GENERATEDFRAME_H__

GeneratedFrame.cpp

#include "GeneratedFrame.h"

MainFrame::MainFrame( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
m_mgr.SetManagedWindow(this);
m_mgr.SetFlags(wxAUI_MGR_LIVE_RESIZE);

m_panelMainView = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_panelMainView->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_ACTIVECAPTION ) );
m_panelMainView->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_INFOBK ) );

m_mgr.AddPane( m_panelMainView, wxAuiPaneInfo() .Name( wxT("MainView") ).Center() .Caption( wxT("Main View") ).MinimizeButton( true ).PinButton( true ).Dock().Resizable().FloatingSize( wxDefaultSize ).Floatable( false ) );

m_menubar2 = new wxMenuBar( 0 );
this->SetMenuBar( m_menubar2 );


m_mgr.Update();
this->Centre( wxBOTH );
}

MainFrame::~MainFrame()
{
m_mgr.UnInit();

}

AppFrame.h

#ifndef __AppFrame_h__
#define __AppFrame_h__

#include "GeneratedFrame.h"
#include "SimpleAuiApp.h"

class AppFrame : public MainFrame
{
public:
// Constructor/Descructor
AppFrame( wxWindow* parent, ApplicationData* pAppData );
~AppFrame( );

// display update (called from main App on an update event)
void UpdateDisplay( );

private:
// pointer to the main data structure
ApplicationData* m_pAppData;

void OnPaint( wxPaintEvent& event );
};

#endif //__AppFrame_h__

AppFrame.cpp

#include "AppFrame.h"
#include "SimpleAuiApp.h"

#include <iostream>

// Constructor for the frame
AppFrame::AppFrame( wxWindow* parent, ApplicationData* pAppData )
: MainFrame( parent )
{
// Pull in the app data pointer
m_pAppData = pAppData;

// Set the size of the inner drawing area of the frame
SetClientSize( 500, 500 );

// Show the frame
Show();

// Layout the frame
Layout();

// Bind to the wxEVT_PAINT event
Bind( wxEVT_PAINT, &AppFrame::OnPaint, this );
}

// Destructor for the frame
AppFrame::~AppFrame( )
{
// stop the update timer for the application, otherwise a timer update
// event can be generated while data is being deleted
if( m_pAppData->m_pTimer )
{
m_pAppData->m_pTimer->Stop( );
}
}

void AppFrame::OnPaint( wxPaintEvent& event )
{
std::cout << "Running AppFrame::OnPaint\n";
UpdateDisplay( );
}

// perform frame update for the display
void AppFrame::UpdateDisplay( )
{
std::cout << "Running AppFrame::UpdateDisplay\n";
}

SimpleAuiApp.h

#ifndef __SimpleAuiApp_h__
#define __SimpleAuiApp_h__

#include <wx/wx.h>

#define DEFAULT_UPDATE_RATE (10) // in Hz (set to 0 for OnIdle)

// Forward declarations
class AppFrame;

struct ApplicationData
{
// constructor
ApplicationData( )
{
m_pFrame = NULL;
m_pTimer = NULL;
m_nDisplayUpdateRate = DEFAULT_UPDATE_RATE;
}

// timer object for frame based updates
wxTimer* m_pTimer;

// rate of display update (in HZ) (0=update on idle)
int m_nDisplayUpdateRate;

// pointer to the main frame instance
AppFrame* m_pFrame;
};

// Main application class
// (derived from the wxWidget App class)
class SimpleAuiApp : public wxApp
{
public:

SimpleAuiApp( );
virtual ~SimpleAuiApp( );

// the main application data structure
ApplicationData m_AppData;

private:

// called by wxApp when starting up, program setup should be done here
bool OnInit( );

// called by wxApp when shutting down, program cleanup should be done here
int OnExit( );

// When running with "fixed" framerate, called for each timer event (frame)
void OnTimer( wxTimerEvent& event );
};

DECLARE_APP( SimpleAuiApp )

#endif //__SimpleAuiApp_h__

SimpleAuiApp.cpp

#include <wx/wx.h>

#include "SimpleAuiApp.h"
#include "AppFrame.h"

#include <iostream>

IMPLEMENT_APP( SimpleAuiApp )

SimpleAuiApp::SimpleAuiApp( )
{
}

SimpleAuiApp::~SimpleAuiApp( )
{
}

bool SimpleAuiApp::OnInit( )
{
// Open a console window for errors and standard output
AllocConsole( );
freopen( "CONOUT$", "wb", stdout );
freopen( "CONOUT$", "wb", stderr );

std::cout << "Initialization started...\n";

// Create the main application frame
m_AppData.m_pFrame = new AppFrame( (wxWindow*) NULL, &m_AppData );

// Bring the frame to the front
SetTopWindow( m_AppData.m_pFrame );

// See if a fixed frame rate is specified
if ( m_AppData.m_nDisplayUpdateRate > 0 )
{
// Start a timer to update the display at a fixed frame rate.
// Note that rate is increased by 10% to make up for wxWidget's inaccurate timers.
m_AppData.m_pTimer = new wxTimer( this );
float fMilliSeconds = 1000.0 / ( m_AppData.m_nDisplayUpdateRate * 1.1f );
m_AppData.m_pTimer->Start( fMilliSeconds );
Bind( wxEVT_TIMER, &SimpleAuiApp::OnTimer, this );
}
else
{
// capture the "on idle" event when not running at a fixed frame rate
Bind( wxEVT_IDLE, &SimpleAuiApp::OnIdle, this );
}

std::cout << "Initialization completed...\n";

return true;
}

// -------------------------------------------------------------
// Framerate - functions bound to framerate related events.
// Either OnTimer() or OnIdle() should be called here for each
// frame, but never both. They are two different refresh
// methods.
// -------------------------------------------------------------

// Called by widget app code on timer event
void SimpleAuiApp::OnTimer( wxTimerEvent& event )
{
std::cout << "Called SimpleAuiApp::OnTimer \n";
// update the frame's display
m_AppData.m_pFrame->UpdateDisplay( );
}

// -------------------------------------------------------------
// OnExit - Called by widget app code on shutdown
// -------------------------------------------------------------
int SimpleAuiApp::OnExit( )
{
// stop (and delete) the update timer if needed
if ( m_AppData.m_pTimer )
{
m_AppData.m_pTimer->Stop( );
delete m_AppData.m_pTimer;
m_AppData.m_pTimer = NULL;
}

// close the console window if needed
FreeConsole( );

// exit successful
return 0;
}

最佳答案

问题最终是您附加到主框架的 AUI 管理器在传播时确实消耗了 wxEVT_PAINT 事件,并且它永远不会到达框架的类。但是,Frame 的子级会收到事件。

我没有使用 Frame 类中的 Bind(),而是调用了 m_panelgl->Bind,其中 m_panelgl 是我的子容器,它包含 OpenGL Canvas 。

关于c++ - 带有 AUI : OpenGL render loop method and wxPaintEvent 的 wxWidgets,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30809720/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com