【问题标题】:Save TPanel as image on disk将 TPanel 保存为磁盘上的图像
【发布时间】:2014-06-20 04:31:21
【问题描述】:

我的一个表单上有一个 TPanel 组件。这个面板有很多子组件,例如 TLabel、TImage、TLine、TPanel 等。这个面板用于在计时器上更新。 我想随时截取此面板的屏幕截图。 当我只使用 TPanel.MakeScreenshot 时,它只显示像 TImage 和 TLine 这样的孩子。缺少 TLabel。

有没有人知道如何实现它。

我正在使用 Delphi XE5 和 firemonkey

谢谢。

【问题讨论】:

  • 刚刚用 XE5/XE6 进行了小测试,它捕获 TLabel 没有任何问题。您应该提供有关您的项目/表单的更多详细信息。如果无法复现,那我估计也帮不了你了。
  • 在我的例子中,TPanel 是一种动态的孩子。 TPanel 的子节点由后台线程不断更新。
  • 将重现问题所需的所有信息放入描述中。尝试仅使用您提供的描述在新项目中使用所有默认设置复制它。
  • TLabels 是否有可能是在代码中创建的,而不是在 IDE 中的表单上创建的?如果是这样,您可能没有正确地养育他们。它们可能会出现在屏幕上,但不会连接到 TPanel。我会将标签放在 IDE 中的表单上,然后在表单的 OnCreate 中将它们设置为空字符串或初始值所需的任何值。如果您使用多线程来更新它们,那么您可以通过某种关键部分直接访问它们,或者将消息发送到它可以用来自行更新它们的表单。就个人而言,我会选择后者。

标签: delphi firemonkey delphi-xe5 firemonkey-fm2


【解决方案1】:

我曾经在制作一个组件来捕获 TLayout 的内容时遇到过类似的问题。在测试中,使用 TLayout.MakeScreenshot 截取的屏幕截图中没有显示某些组件。

这是因为当您在代码中创建 TLabel 时,当您将其作为 TPanel 的父级时,它不会自动绘制。它仅在第一次实际显示时才绘制。因此,如果你这样做,标签将不会显示:

var
  NewLabel: TLabel;
  Shot: TBitmap;
...
  NewLabel := TLabel.Create;
  NewLabel.Parent := Panel1; // I suppose you are setting the parent like this in your code
  NewLabel.Text := 'some new label';
  Shot := Panel1.MakeScreenshot;

要使标签显示,您必须在 TPanel 画布上绘制它们。我用 ApplyStyleLookup 方法做到了,比如:

  ...
  NewLabel.Text := 'some new label';
  NewLabel.ApplyStyleLookup;
  Shot := Panel1.MakeScreenshot; // Now the label will show

您必须为每个标签调用 ApplyStyleLookup 才能使它们出现。

如果将 TLabel 的 AutoSize 设置为 true 并设置文本也是一样的。标签的宽度在实际显示在表单上之前不会调整。
我没有在 FMX 源代码中详细查看这个,但可能是某个地方的错误,因为它只影响某些组件。

您还没有显示您的代码,所以我不确定这是否是同一个问题,但听起来确实如此。

顺便说一句,您可能知道您不能直接从另一个线程更新 FMX 控件,因为它们不是线程安全的,对吧?而且你还释放了从 MakeScreenshot 返回的 TBitmap?

【讨论】:

    猜你喜欢
    • 2011-10-31
    • 2015-06-23
    • 1970-01-01
    • 2020-05-10
    • 2021-10-13
    • 1970-01-01
    相关资源
    最近更新 更多