【问题标题】:How to use cairo to draw custom controls on Linux wxWidgets as with GDI+ on Windows wxWidgets?如何使用 cairo 在 Linux wxWidgets 上绘制自定义控件,就像在 Windows wxWidgets 上使用 GDI+ 一样?
【发布时间】:2021-02-07 05:12:16
【问题描述】:

在使用 Code::Blocks 的 Windows 上,我曾经在 wxWidgets 自定义控件中调用 this->GetHandle() 来获取 HWND 句柄,以便从哪里使用 GDI+ 库进行绘制。在 Linux 中做同样的事情时,当我从绘图事件处理程序调用 this->GetHandle() 时,我得到一个 GtkWidget*,但我不知道如何使用 cairo 库与 GDI+ 一起呈现自定义控件。我尝试了一些来自互联网的 cairo 渲染示例,但老实说没有用。

在自定义控件中,我在绘制事件处理程序中有这个

void WorkingArea::paintEvent(wxPaintEvent& event)
{
    wxPaintDC dc(this);
    render(dc);
}

渲染函数是这样的

void WorkingArea::render(wxDC& dc)
{
     Render(this->GetHandle(),graph);
    //In windows I just call Render((HWND)this->GetHandle(),graph);
}

在 Windows 中渲染函数如下

void Render(HWND window_handle,const Simple2DGraph& graph)
{
    delete gw;//deletes window graphic
    gw=Graphics::FromHWND(window_handle);
    delete g;     //deletes buffer bitmap graphic
    delete buffer;//deletes the buffer bitmap
    ctrlW=graph.getCtrlW();
    ctrlH=graph.getCtrlH();
    buffer=new Bitmap(ctrlW,ctrlH,gw);
    g=Graphics::FromImage(buffer);
    //Graphics buffer settings
    g->SetCompositingMode(CompositingMode::CompositingModeSourceOver);
    g->SetCompositingQuality(CompositingQuality::CompositingQualityHighSpeed);
    g->SetInterpolationMode(InterpolationMode::InterpolationModeBicubic);
    g->SetPageScale(1);
    g->SetPageUnit(Unit::UnitPixel);
    g->SetPixelOffsetMode(PixelOffsetMode::PixelOffsetModeHighSpeed);
    g->SetSmoothingMode(SmoothingMode::SmoothingModeHighQuality);
    g->SetTextRenderingHint(TextRenderingHint::TextRenderingHintSystemDefault);
    g->Clear(color1);
    //->
    //->
    //->
    //More rendering commands
}

我使用传递的 HWND 创建一个 Windows 图形,在其中我使用 GDI+ 库绘制对象。我想知道如何使用 cairo 库方法从获得的 GtkWidget* 呈现自定义控件,就像我可以在 Windows 上使用传递的 HWND 创建的 GDI+ 图形一样。

【问题讨论】:

  • 你试过 wxGraphicsContext、wxRendererNative 吗?
  • 是的,我也尝试过。该代码创建了 cairo_t 和所有内容,但在屏幕上不呈现任何内容。它只显示一个空白的白色窗口。
  • 构建并运行 wxW 附带的drawing 示例。打开Drawing 菜单并选择Use default wxGraphicsContext。你是否也看到了一个空白的白色窗口?

标签: render codeblocks wxwidgets cairo


【解决方案1】:

你到底想做什么? IE。当然,您的最终目标不是“使用开罗”,而是实际绘制一些东西,不是吗?如果是这种情况,您应该按照评论中的建议使用wxGraphicsContext

如果没有,基本上你需要直接使用 GTK API,有很多使用 Cairo 和 GTK 的例子。但是,这再次违背了使用 wxWidgets 隐藏平台之间差异的整个想法——这正是 wxGraphicsContext 所做的(因为它在 Windows 和 Unix 系统下内部使用 GDI+ 或 Direct2D)。

【讨论】:

  • 我尝试了您的解决方案,但它不起作用。我在 wxWidgets 项目中使用 code::blocks 来制作 gui。当我从 GetHandle 获得 GtkWidget* 时(记住我使用的是 Linux)它什么也不做,无论我使用 wxGraphicsContext 还是其他方式
  • 我认为解决方案与 GTK 中的事件信号有关,那么如何重新绑定信号和函数回调以绘制小部件?
  • 使用 wxWidgets,您可以从 wxEVT_PAINT 处理程序进行绘制。如果你不想在这个窗口中使用 wxWidgets,你应该在 GTK 级别完全实现它并使用wxNativeWindow 嵌入它。目前还不清楚你到底想做什么。
  • 这很简单,我正在使用 wxWidgets 来做常规的 GUI,例如菜单和按钮,但我需要一个具有非常复杂的绘图和合成的自定义控件。我打算从每个操作系统(Windows 中的 GDI+ 和 Linux 中的 GTK+)中的本机 API 中绘制所有控件,并从 wxWidgets 对象的 GetHandle 方法中返回的句柄开始。由于某种原因被评论的解决方案不起作用,除此之外我需要使用保存和恢复图形状态的功能以节省渲染时间。
  • 我必须补充一点,控件比具有不同形状的自定义按钮复杂得多,但比游戏简单得多。该应用程序旨在在没有 GPU 的机器上运行,因此我需要使用 GDI+ 和 GTK+ API 尽我所能
猜你喜欢
  • 1970-01-01
  • 2010-09-16
  • 2014-10-12
  • 2012-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-01
  • 2010-12-26
相关资源
最近更新 更多