PyGTK Z-order doesn't seem to work - python

I am working on a chat GUI, and I'm trying to put a send button on top of the TextView. I'm using a Table, and I'm attaching both widgets to the same place. The positioning of the widgets is determined by the Alignment containers that I'm putting them both in. The problem is that the TextView covers up the image (I'll make it respond to clicks later). I tried making the image's alignment rise in the Z-order by using align2.window.raise_(), but that didn't change anything. I also tried doing all of the .show()'s manually to make sure that the image's came last, but that didn't work either.
How can I keep the TextView from covering up the image while still letting it take up all the room it can get?
Here is my basic code:
align1 = gtk.Alignment(0, 0, 1, 1)
align2 = gtk.Alignment(1)
table = gtk.Table()
window.add(table)
table.attach(align1, 0, 1, 0, 1)
table.attach(align2, 0, 1, 0, 1)
textview = gtk.TextView()
align1.add(textview)
im = gtk.image_new_from_file("/home/commandant/Desktop/send.png")
align2.add(im)
window.connect('destroy', gtk.main_quit)
window.show_all()
gtk.main()

Related

Python tkinter scrollbar handle not accurately represented

I've created a scrollbar widget in tkinter and connected it to a Listbox widget. I can scroll, use the arrows and drag the handle up and down perfectly fine. When I let go however, the handle teleports to the top of the scrollbar, and I don't understand why.
Here's a gif showing the problem:
And here's my code
self.chattHistoryScrollbar = tk.Scrollbar(self.upperFrame)
self.chattHistoryScrollbar.grid(row = 0, column = 1, sticky = 'NSE')
self.chattHistoryScrollbar.config(command = self.chattHistory.yview)
Any ideas what I'm doing wrong?

How base object controls the camera in Panda3d

I was toying around with creating custom geometry in Panda3d engine. And next code works 100% correct.
class FooBarTriangle(ShowBase):
def __init__(self):
super(self).__init__()
self.disable_mouse()
self.set_frame_rate_meter(True)
self.accept("escape", sys.exit)
self.accept("space", lambda: print(self.camera.get_pos()))
self.camera.set_pos(0, 0, 10)
self.camera.look_at(0, 0, 0)
self._add_light()
self._add_triangle()
def _add_light(self):
# Adds a point light
pass
def _add_triangle(self):
# Adds a single triangle in a certain place
pass
Mysterious things happen when I remove base.disableMouse() from my code. I expect my camera to be movable and appear in the (0, 0, 10) position, looking at (0, 0, 0). But, instead, camera is in the position (0, 0, 0) and I don't know where does it look.
Why does it happen?
This happens, because Panda3D has a default camera control in place (the default camera driver), if you don't call disableMouse(), Panda3D will not move your camera through calls to camera.set_pos(x, y, z), but only allow movement through the specified controls as can be read up here and here in the manual.
You either have to write your own camera controller if you wish to be able to place your camera anywhere other than (0, 0, 0) through code or just use the controls indicated on the links above to move around the scene.

How can I get color properties of all actors?

(This might be an easy question. However I don't know the solution.)
I made an simple multi-STL files viewer using PyQt5 and VTK library.
There is rendering widget (QVTKRenderWindowInteractor) and a reset button (QPushButton).
If I click the reset button, the color of the actors (all loaded STL data) are changed to white.
Following code is the reset button click function
(It works well):
def _resetBtnClicked(self):
# reset actor colors
actorCollection = self.ren.GetActors()
actorCollection.InitTraversal()
cactor = actorCollection.GetNextActor() # first actor
while cactor != actorCollection.GetLastActor():
cactor.GetProperty().SetColor(1, 1, 1)
cactor = actorCollection.GetNextActor()
cactor.GetProperty().SetColor(1, 1, 1) # last actor
The self.ren is the vtk.vtkRenderer() and I used while roop to deal with ACTORs COLOR using .GetNextActor(), sequently.
However, I want to change the while loop to a simple code, like self.ren.GetActors().GetProperty().SetColor(1, 1, 1) if possible (this 'self.ren.GetActors().GetProperty().SetColor(1, 1, 1)' isn't existed).
If there are several function I can use instead of while roop, please let me know.

Eliminate unnecessary drawing of an image when using dc?

I have three questions that I could really use some help on. Hope I'm not asking too much.
1) I am designing a simple GUI that contains one frame and one panel. Let's say I have two images that I draw on the panel using dc. One image will be continually fade in and out (on a timer), and the second is stationary (doesn't change). The fading is accomplished by changing the opacity of the image and use dc.Clear() before redrawing the new version of the image.
My question is this: how would I draw the fading in/out image without affecting the second image which does not change? It seems like this causes unnecessary drawing as the stationary image will be redrawn alongside the fading image. Could I selectively clear just the first image without affecting the second? This is my drawing function:
def on_paint(self, event):
dc = wx.PaintDC(self)
dc = wx.BufferedDC(dc)
brush = wx.Brush('#3B3B3B')
dc.SetBackground(brush)
dc.Clear()
# Draw the first image (stationary)
dc.DrawBitmap(stationaryBitmap, 120, 0, True)
# Draw the second image (fading)
image = self.image.AdjustChannels(1, 1, 1, self.factoralpha)
fadingBitmap = wx.BitmapFromImage(image)
dc.DrawBitmap(fadingBitmap, 120, 0, True)
2) How can I bind an event to a wx.Image object? I would like to be able to click on the fading in/out image, though I can't seem to assign it an id. The goal is to bind an event similar to what I could do with a wx.StaticBitmap.
self.image = wx.Image("C:\image.png", wx.BITMAP_TYPE_PNG)
# Trying to bind an event, but no ID is assigned
self.Bind(wx.EVT_BUTTON, self.go_button, id=self.image.GetId())
3) Is it possible to place wx.DrawBitmap in a sizer? It appears that it only takes an x,y coordinate pair.
dc.DrawBitmap(bitmap, 120, 0, True)
Thanks everyone.
1) For the Performance, I would recommend using a MemoryDC and update the Drawing only it is required. See here: BufferedCanvas. You may want to use more than 2 buffers because you are using 2 images (see example).
2) I don't know about this, but have you tried to do the binding to a panel and fade the panel in/out?
You can directly paint on a wx.Panel.
Regards

drawing a pixbuf onto a drawing area using pygtk and glade

i'm trying to make a GTK application in python where I can just draw a loaded image onto the screen where I click on it. The way I am trying to do this is by loading the image into a pixbuf file, and then drawing that pixbuf onto a drawing area.
the main line of code is here:
def drawing_refresh(self, widget, event):
#clear the screen
widget.window.draw_rectangle(widget.get_style().white_gc, True, 0, 0, 400, 400)
for n in self.nodes:
widget.window.draw_pixbuf(widget.get_style().fg_gc[gtk.STATE_NORMAL],
self.node_image, 0, 0, 0, 0)
This should just draw the pixbuf onto the image in the top left corner, but nothing shows but the white image. I have tested that the pixbuf loads by putting it into a gtk image. What am I doing wrong here?
You can make use of cairo to do this. First, create a gtk.DrawingArea based class, and connect the expose-event to your expose func.
class draw(gtk.gdk.DrawingArea):
def __init__(self):
self.connect('expose-event', self._do_expose)
self.pixbuf = self.gen_pixbuf_from_file(PATH_TO_THE_FILE)
def _do_expose(self, widget, event):
cr = self.window.cairo_create()
cr.set_operator(cairo.OPERATOR_SOURCE)
cr.set_source_rgb(1,1,1)
cr.paint()
cr.set_source_pixbuf(self.pixbuf, 0, 0)
cr.paint()
This will draw the image every time the expose-event is emited.
I found out I just need to get the function to call another expose event with widget.queue_draw() at the end of the function. The function was only being called once at the start, and there were no nodes available at this point so nothing was being drawn.

Categories

Resources