DirectGUI Basic Question

Hello everyone,

I have been experiencing issues with buttons in DirectGUI when parenting to pixel2d. Most specifically, I cannot see my button’s text and relief whenever I change to pixel2d. Here is an example of the code I am using:

file_button = DirectButton(text = "File",
                           frameColor = ((0.2,0.2,0.2,1), (0.4,0.3,0.3,1), (0.4,0.4,0.4,1),(0.1,0.1,0.1,1)),
                           frameSize = (0,50,0,25),
                           pos=(0, -2, -25),
                           relief = DGG.SUNKEN,

I have looked for examples of buttons in the manual, forums and the Panda3D Game Development Book, but none of them that I found where in pixel2d.

While this is my major question, I would also greatly appreciate any examples on the following things:

  • Attaching an image to a button in pixel2d
  • Changing font style
  • Changing font color

Thanks in advance,

In fact, you need to attach aspect2d.

        self.start = DirectButton(
        pos=(0, 0, -0.4), 
        image_scale=(0.2, 0, 0.1), 

Old code I found.

Is there no way to properly attach buttons to pixel2d? What if I want to specifically specify the scale and position of my GUI in pixels? There is already support for other GUI components in pixel2d.

Perhaps the problem is that by default DirectGUI is attached to aspect2d. Perhaps it should be unhooked from the aspect2d node, you will need to check.

Yes, the parent of any DirectGUI component seems to be by default aspect2d. However you can change the parent by either using the “reparentTo” method or just passing into the constructor of the component “parent = …”.

I also noticed that the pixel2d node has conversions:

 PGTop pixel2d T: (pos -1 0 1 scale 0.0025 1 0.00333333) S: (CullBinAttrib)

Perhaps this is a problem, in fact, I use the Cartesian system of the arrangement of elements, I am not familiar with pixel2d.

It is fairly simple if I am not mistaken, for positioning, the x and y coordinates are represented by Point3(x,0,-y), while the size in terms of width and height is represented by (-width, 0, 0, height), and the origin is top left corner of the screen.

I think that the issue is likely one of scale: pixel2d operates in a different coordinate-range than does aspect2d (for most window-sizes, at least).

Specifically, aspect2d ranges from -1 to 1 in the vertical, and along a similar range on the horizontal, with the exact values depending on the aspect-ratio of the window. On the other hand, pixel2d ranges from 0 to the -(height of the window) in the vertical, and 0 to the width of the window in the horizontal.

As a result, the scales appropriate to things like text-size and border-size may differ.

A quick example:

btn = DirectButton(text = "Mew",
                           parent = pixel2d,
                           pos = (100, 0, -100),
                           frameSize = (0,50,0,25),
                           borderWidth = (5, 5),
                           text_scale = 20)

You may want to play around with the “text_pos” keyword-parameter, too, to get the text in the right location.

As to attaching an image, that depends on quite what you want to do. You can texture it over the entire button via the “frameTexture” keyword-parameter, or add it as a separate card via the “image” keyword-parameter, I think. (If you use the latter option, note the various “image_” parameters that control its size, position, etc. See this page.)

I think that font-colour is similarly controlled by a keyword-parameter.

As to fonts, the manual gives a description of them on this page. In addition to what’s described there, you can also manually construct a “DynamicTextFont” object, passing in as a parameter the file-name of the the font in question (and most likely the value “0” as the second parameter).

You then apply the font via the “text_font” keyword-parameter, I believe.

1 Like

Thanks a lot for the answer, with your example I can see that for pixel2d you need to define the borderWidth and adjust the position of the text in order to be where you’d expect it. While manually adjusting the position of the text can be a bit of a lengthy process, it is definitely worth the effort.

It’s my pleasure; I’m glad if I’ve helped. :slight_smile:

Perhaps for a future update of Panda3D it would be a good idea to automatically set the text within the center of the button (like in aspect2d).

It sounds good, but it’s not clear how it will scale. If the element is located in the lower right corner, say 1920, –1080, this is at this resolution. But if the user changes the resolution of 800 600. It will be necessary to check.


I checked: the not be scaled either, it just goes beyond the screen.

Yup: My understanding is that pixel2d simply works on pixel-values: an object with a width of 10 occupies ten pixels in the horizontal, regardless of window-size.

(I may be mistaken, of course, and stand to be corrected.)

I do not think that anything parented to pixel2d can change scale, a component is defined as a fixed size in terms of pixels, located at a fixed position of pixels relative to the top left corner. You can also emulate the behavior of aspect2d by taking into factor the size of the window and updating your components whenever the window is resized. However unlike aspect2d, you can also define fixed sizes in terms of pixels. This can be very useful, especially if you want to define the position and size of GUIs as a mixture of both the variable window sizes but also fixed pixel intervals.

I just do code to determine the edge of the screen when using aspect2d.

pos = (base.getAspectRatio()-0.15,0,0.85)


Yes, this is good, however imagine wanting your GUI to have a variable size depending on the window size but to never go under a certain number of pixels (say 20 by 20 pixels). Doing that with aspect2d would be rather inconvenient, if possible at all, whereas for pixel2d, your size is defined as a variable that depends on the screen size + a fixed value, for this example, 20. Another useful case would be wanting two components be a certain number of pixels apart no matter the screen size. Yet again pixel2d is much more convenient. And lastly, for the most obvious example, if you just want to define everything in fixed pixel quantities, pixel2d will make your life a lot easier.

In fact, in the video, my GUI is scaled at any resolution.

Yes, of course, however imagine trying to accomplish the 3 things I described above, using aspect2d. I don’t think it would be easy, if possible at all for some of them.

For your example, imagine downsizing your GUI all the way to minimum window size. While everything would remain in place, your components would shrink to almost zero.

Now take a look at some famous software, say Blender3D. Do you see the GUI components shrinking to almost zero when you attempt to resize the window to a smaller scale?

My point is, there is good reason sometimes to use pixel values for GUIs, which is why I want to use pixel2d.

I understand, you will have too small image in small resolution. But I don’t think anyone uses a resolution of 320 on 240 a PC.

Yes, it is not a common resolution, however you never know how your application will expand, perhaps someday on tablet, console or mobile. And while this tends to be the case, it is also a matter of just wanting the GUI to “look good” regardless of how the user decides to change their resolution.