gtk#nodeview上的工具提示在不正确的行上显示

发布于 2025-02-08 17:19:55 字数 2308 浏览 2 评论 0原文

GTK#NodeView Instances中显示工具提示的方式似乎有一些有趣的行为。具体而言,GetPathatpos方法在返回treepath时不会考虑标头行,这又导致工具提示在不正确的行下显示。以下代码被用来证明问题:

using Gtk;

[TreeNode(ListOnly = true)]
public class MyTreeNode : TreeNode
{
    [TreeNodeValue(Column = 0)]
    public string RowNumber { get; set; } = "";

    [TreeNodeValue(Column = 1)]
    public string Data { get; set; } = "";
}

public partial class MainWindow : Gtk.Window
{
    public MainWindow() : base(Gtk.WindowType.Toplevel)
    {
        Build();

        nodeview1.AppendColumn("Row Number", new CellRendererText(), "text", 0);
        nodeview1.AppendColumn("Data", new CellRendererText(), "text", 1);

        NodeStore nodeStore = new NodeStore(typeof(MyTreeNode));

        nodeStore.AddNode(new MyTreeNode { RowNumber = "One", Data = "foo" });
        nodeStore.AddNode(new MyTreeNode { RowNumber = "Two", Data = "bar" });
        nodeStore.AddNode(new MyTreeNode { RowNumber = "Three", Data = "baaz" });
        nodeStore.AddNode(new MyTreeNode { RowNumber = "Four", Data = "quux" });

        nodeview1.NodeStore = nodeStore;
        nodeview1.HasTooltip = true;
        nodeview1.QueryTooltip += Nodeview1_QueryTooltip;
    }

    private void Nodeview1_QueryTooltip(object o, QueryTooltipArgs args)
    {
        bool result = false;

        if (nodeview1.GetPathAtPos(args.X, args.Y, out TreePath path))
        {
            TreeModel model = nodeview1.Model;

            if (model.GetIter(out TreeIter iter, path))
            {
                string rowNumber = model.GetValue(iter, 0) as string;

                args.Tooltip.Text = "This is the tooltip for Row Number " + rowNumber;
                result = true;
            }
        }

        args.RetVal = result;
    }

    protected void OnDeleteEvent(object sender, DeleteEventArgs a)
    {
        Application.Quit();
        a.RetVal = true;
    }
}

将鼠标悬停在rownumber =“三”的行上时,该工具提示说:“这是第四行的工具提示”。同样,当将鼠标悬停在标头上时,该工具提示说:“这是第一排的工具提示”。所有工具提示都以这种方式行事。

作为解决方法,我修改了呼叫getPathatpos通过“ args.y -23”。标题行似乎高23像素,但是当然,硬编码这些类型的值不是很好的做法。

希望其他人以前已经经历过这种情况,并且知道如何解决它或如何更动态地解决它(例如,知道如何在运行时获得标头行的高度)。

该代码已使用Ubuntu 22.04 LTS上的Monodevelop 7.8.4(构建2)编译。需要注意的两件事:

  1. 单座管仅支持GTK 2(除非有人知道如何获得支持新版本)。
  2. 我在VirtualBox会话中运行Ubuntu,Windows 10作为主机操作系统。

There appears to be some interesting behavior with the way tooltips are being displayed in Gtk# NodeView instances. Specifically, the GetPathAtPos method is not taking the header row into consideration when returning the TreePath, which in turn causes the tooltip to be displayed under an incorrect row. The following code is being used to demonstrate the issue:

using Gtk;

[TreeNode(ListOnly = true)]
public class MyTreeNode : TreeNode
{
    [TreeNodeValue(Column = 0)]
    public string RowNumber { get; set; } = "";

    [TreeNodeValue(Column = 1)]
    public string Data { get; set; } = "";
}

public partial class MainWindow : Gtk.Window
{
    public MainWindow() : base(Gtk.WindowType.Toplevel)
    {
        Build();

        nodeview1.AppendColumn("Row Number", new CellRendererText(), "text", 0);
        nodeview1.AppendColumn("Data", new CellRendererText(), "text", 1);

        NodeStore nodeStore = new NodeStore(typeof(MyTreeNode));

        nodeStore.AddNode(new MyTreeNode { RowNumber = "One", Data = "foo" });
        nodeStore.AddNode(new MyTreeNode { RowNumber = "Two", Data = "bar" });
        nodeStore.AddNode(new MyTreeNode { RowNumber = "Three", Data = "baaz" });
        nodeStore.AddNode(new MyTreeNode { RowNumber = "Four", Data = "quux" });

        nodeview1.NodeStore = nodeStore;
        nodeview1.HasTooltip = true;
        nodeview1.QueryTooltip += Nodeview1_QueryTooltip;
    }

    private void Nodeview1_QueryTooltip(object o, QueryTooltipArgs args)
    {
        bool result = false;

        if (nodeview1.GetPathAtPos(args.X, args.Y, out TreePath path))
        {
            TreeModel model = nodeview1.Model;

            if (model.GetIter(out TreeIter iter, path))
            {
                string rowNumber = model.GetValue(iter, 0) as string;

                args.Tooltip.Text = "This is the tooltip for Row Number " + rowNumber;
                result = true;
            }
        }

        args.RetVal = result;
    }

    protected void OnDeleteEvent(object sender, DeleteEventArgs a)
    {
        Application.Quit();
        a.RetVal = true;
    }
}

When hovering the mouse over the row where RowNumber = "Three", the tooltip says, "This is the tooltip for Row Number Four". Similarly, when hovering the mouse over the header, the tooltip says, "This is the tooltip for Row Number One". All of the tooltips behave this way.

As a workaround, I modified the call to GetPathAtPos to pass "args.Y - 23". The header row appears to be 23 pixels high, but of course it is not good practice to hard-code these types of values.

Hopefully someone else has experienced this before and knows how to resolve it or how to work around it more dynamically (for example, knowing how to get the height of the header row at runtime).

The code has been compiled using MonoDevelop 7.8.4 (build 2) on Ubuntu 22.04 LTS. Two things to note:

  1. MonoDevelop supports only GTK 2 (unless anyone knows how to get it to support newer versions).
  2. I am running Ubuntu in a VirtualBox session, with Windows 10 as the host operating system.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

流殇 2025-02-15 17:19:55

进行了一些挖掘之后,包括找到一个很棒的 visual 能够找到解决方案。 QueryToolTipargs中的X和Y值在小部件坐标中。他们需要将它们转换为bin窗口坐标,以使getPathatpos正确工作。结果,nodeview1_querytooltip中的if语句已修改如下:

原始代码:

if (nodeview1.GetPathAtPos(args.X, args.Y, out TreePath path))

更新代码:

nodeview1.ConvertWidgetToBinWindowCoords(args.X, args.Y, out int bx, out int by);
if (nodeview1.GetPathAtPos(bx, by, out TreePath path))

After doing some digging that included finding a great visual for Gtk.TreeView, I was able to find a solution. The X and Y values in QueryTooltipArgs are in widget coordinates. They need to be translated to bin window coordinates for GetPathAtPos to work correctly. As a result, the if statement in Nodeview1_QueryTooltip has been modified as follows:

ORIGINAL CODE:

if (nodeview1.GetPathAtPos(args.X, args.Y, out TreePath path))

UPDATED CODE:

nodeview1.ConvertWidgetToBinWindowCoords(args.X, args.Y, out int bx, out int by);
if (nodeview1.GetPathAtPos(bx, by, out TreePath path))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文