您将如何构建“像素完美”的应用程序? Linux 上的图形用户界面?
我想构建一个 GUI,其中每个像素都在我的控制之下(即不使用 GTK+ 等提供的标准小部件)。 Renoise 是我想要制作的一个很好的例子。
深入到 Xlib 或 XCB 级别是最好的方法吗?或者是否可以使用 GTK+(甚至 PyGTK)等更高级别的框架来实现这一目标?我应该去开罗看图吗?
如果可能的话,我想使用 Python 或 Ruby 工作,但 C 也可以。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
使用 Clutter 工具包(或其他一些画布小部件/工具包),您可以构建这样的界面。我不建议进入 Xlib/XCB 或 DrawingArea 级别,因为它需要实现画布中已有的许多通用功能。
With Clutter toolkit (or some other canvas widget/toolkit) you can build such an interface. I would not advise going to the level of Xlib/XCB or DrawingArea because it would require implementing much of generic functionality already present in canvases.
在 X 中,这种方法有一个您可能没有考虑到的问题。字体大小以点为单位(1 点为 1/72 英寸),因此(像素)大小会随分辨率和显示器尺寸的变化而变化。文本字符串的长度也会根据语言而变化,因此实际上不可能确定按钮等需要多大。 X 的通用 GUI 工具包在设计时就考虑到了这一点。除此之外,很容易为 GTK 编写自己的主题引擎,完全按照您想要的方式绘制所有小部件(使用 Cairo[1] 或 GDK[2]),并使您的应用程序始终使用该主题。也许您的应用程序也可以根据 DPI 设置默认字体大小(以磅为单位),以始终获得相同的像素大小(当然不会使您的应用程序可翻译)。
至少有几个 GUI 使用这种基于 SDL[3] 的像素完美方法,例如 AGAR[4]、PicoGUI[5] 和 Guichan[6]。其中大多数是用 C++ 编写的,有些是用 C 编写的,据我所知,它们都没有与 Python 或 Ruby 的绑定。然后使用 SDL,您只能拥有一个顶级窗口,这意味着您的应用程序(或您使用的 GUI 工具包)必须对各种对话框等进行自己的窗口管理。但我想这就是你的意图。
[1] cairgraphics.org/
[2]library.gnome.org/devel/gdk/unstable/index.html
[3] www.libsdl.org/
[4] libagar.org/
[5] picogui.org/
[6] guichan.sourceforge.net/wiki/index.php/Main_Page
In X there is one problem with this approach which you might not have taken into consideration. The font size is measured in points (one point being 1/72 of an inch) and thus varies in (pixel) size with resolution and monitor size. The text strings will also vary in length depending on the language so it's not really possible to determine how large buttons and such need to be. The common GUI toolkits for X are designed with this in mind. Apart from that it would be easy to just write your own theme engine for GTK that draws all widgets exactly as you want them (using Cairo[1] or GDK[2]) and make your application always use that theme. Perhaps it would also be possible for your application to set the default font size (in points) based on the DPI to always get the same size in pixels (and of course not making your application translatable).
There are at least a couple of GUIs using this pixel perfect approach based on SDL[3], for example AGAR[4], PicoGUI[5] and Guichan[6]. Most of them are written in C++ and some in C and as far as I know none of them have bindings for Python nor Ruby. Then using SDL you can only have one top-level window which means your application (or the GUI toolkit you use) have to do its own window managing for various dialogs and such. But I guess that was what you intended anyway.
[1] cairographics.org/
[2] library.gnome.org/devel/gdk/unstable/index.html
[3] www.libsdl.org/
[4] libagar.org/
[5] picogui.org/
[6] guichan.sourceforge.net/wiki/index.php/Main_Page
那么你可能会想要类似 pygame 的东西。
You'll probably want something like pygame then.
GTK 和 PyGTK 可能是错误的工具。这并非不可能,因为您可以让整个应用程序成为一个大的
gtk.DrawingArea
(实际上有意义的一个示例是 Gargoyle),但对于任何类型的复杂 GUI 你都会发疯。GTK and PyGTK are probably the wrong tools to use. It's not impossible, because you could have your entire application be one big
gtk.DrawingArea
(an example of this where it actually makes sense is Gargoyle) but for any sort of complicated GUI you'd go crazy.http://www.oluyede.org /blog/writing-a-widget-using-cairo-and-pygtk-28/ 展示了如何使用 PyGTK 和 Cairo 创建一个简单的小部件。
http://www.oluyede.org/blog/writing-a-widget-using-cairo-and-pygtk-28/ shows how to create a simple widget using PyGTK and Cairo.
用最简单的话来说,你需要一个能给你一个边界矩形和自由支配权的东西,让你可以在其中绘制任何你想要的东西。此类对象通常称为“画布”。我之前(在 Ruby 中)使用通过 Fox 工具包 提供的 FXCanvas 类完成了此操作,但是有还有其他可用的工具吗(例如 wxWidgets,但我没有使用此工具包的个人经验)。
但请注意。像这样的低级接口提供了很大的灵活性,但它们也需要您做更多的工作。
In simplest terms, you need something that gives you a bounding rectangle and free reign to draw into it whatever you want. Such objects are commonly called a "canvas". I have done this before (in Ruby) using the FXCanvas class available through the Fox toolkit, but there are others available as well (wxWidgets, for example, but I have no personal experience with this toolkit).
Be warned, though. Low-level interfaces like this offer a lot of flexibility, but they also require a lot more work on your part.