gtk#nodeview上的工具提示在不正确的行上显示
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)编译。需要注意的两件事:
- 单座管仅支持GTK 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:
- MonoDevelop supports only GTK 2 (unless anyone knows how to get it to support newer versions).
- I am running Ubuntu in a VirtualBox session, with Windows 10 as the host operating system.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
进行了一些挖掘之后,包括找到一个很棒的 visual 能够找到解决方案。 QueryToolTipargs中的X和Y值在小部件坐标中。他们需要将它们转换为bin窗口坐标,以使getPathatpos正确工作。结果,nodeview1_querytooltip中的if语句已修改如下:
原始代码:
更新代码:
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:
UPDATED CODE: