PYGTK uses more screen space than expected - python

I am using PYGTK to program a very simple download manager, using both wGet and Python. Everything does well but it eats up a lot of screen space...
My code:
#!/usr/bin/python
import gtk
import os
def submitdownload(self):
os.system("wget "+site.get_text() + " -P "+ directory.get_text())
main=gtk.Window()
main.set_title("Simple Downloader with wGet")
structure=gtk.Table(2, 6, True)
label=gtk.Label("Simple downloader with wGet")
sitedes=gtk.Label("Your download link:")
site=gtk.Entry()
submit=gtk.Button("Submit download")
submit.connect("clicked", submitdownload)
directorydes=gtk.Label("Save to: ")
directory=gtk.Entry()
description=gtk.Label("Please don't close the black box (terminal window) or the application will close automatically. It is needed for the download.")
main.add(structure)
structure.attach(label, 0, 2, 0, 1)
structure.attach(sitedes, 0, 1, 1, 2)
structure.attach(site, 1, 2, 1, 2)
structure.attach(submit, 0, 2, 4, 5)
structure.attach(directorydes, 0, 1, 2, 3)
structure.attach(directory, 1, 2, 2, 3)
structure.attach(description, 0, 2, 5, 6)
main.connect("destroy", lambda w: gtk.main_quit())
main.show_all()
gtk.main()
It throws a lot of unused space at the right. How to fix that? It's very hard to close the application through the 'X' button.

You appear to be creating a table with 2 rows and 6 columns as opposed to the 6 rows and 2 columns I assume you're after - look at the reference documentation and you'll see rows come first in the constructor.
Because you've set homogenous to True, the table is setting all columns to the same width and height (that's what homogenous does), and because you've asked for 6 columns, it's adding a lot of blank ones of the same width which makes your window tremendously wide.
Change the line to:
structure = gtk.Table(6, 2, True)
... and it seems more reasonable. Was that what you were after?
Personally I would suggest creating a HBox to represent the column. When you need full width widgets, you can just place them directly into this container. If you need a row with multiple widgets, you can create a VBox to represent the row, add the widgets to that and then add the VBox itself to the HBox. This approach may seem slightly fiddlier at first, but it allows GTK to handle more of the layout itself which generally makes your application handle resizing better (as long as you correctly hint whether each widget should be expandable or not). Also, you don't need to go back and change the number of rows and columns if you add more widgets later - VBox and HBox are more flexible in that regard. So overall, I've always found these a lot easier unless what I'm after really is a fixed grid of widgets (e.g. if I'm implementing Minesweeper).

Related

How to remove space between radiobuttons in pyqt5

How To Remove Padding Between Male And Female RadioButtons?
Here's My Code :
def UiComponents(self):
self.gridbox=QGridLayout()
self.label=QLabel("What's Your Gender?")
self.r1=QRadioButton("Male")
self.r2=QRadioButton("Female")
self.r3=QRadioButton("Rather Not To Say")
self.button=QPushButton("Submit")
self.gridbox.addWidget(self.label,0,0)
self.gridbox.addWidget(self.r1,1,0)
self.gridbox.addWidget(self.r2,1,1)
self.gridbox.addWidget(self.r3,1,2)
self.gridbox.addWidget(self.button,2,0)
self.setLayout(self.gridbox)
self.show()
Try changing spacing attribute at setStyleSheet() method like so
r1.setStyleSheet("""
QRadioButton {
spacing : 20px; #(<- example value)
}
""")
QGridLayout works like html table - you got columns and rows, column width is equal to wider widget in column, in your case it's label. To avoid stretching first column, span label across all columns using columnSpan argument of addWidget (and button too).
self.gridbox.addWidget(self.label,0,0,1,3)
...
self.gridbox.addWidget(self.button,2,0,1,3)
I would recomend using QtDesigner to create ui, it saves a lot of time and effort and also wysiwyg.

How does the 'with' statement work in kivy?

I have been playing with kivy, and I saw this:
with self.canvas:
Color(1, 1, 0) # <--- no assignment
d = 30.
Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d)) # <--- no assignment
I don't quite understand how it works. I was expecting to see something like:
with self.canvas as c:
c.color = Color(1, 1, 0)
c.shape = Ellipse()
What am I missing?
with some_canvas sets an internal Kivy variable to that canvas. When canvas instructions are created they check if that variable is set to a canvas, and if so they automatically add themselves to it.
If you want to trace through how this works you can find the context entry function here, and the code that automatically adds instructions to a canvas when instantiated here.
I don't quite understand how it works. I was expecting to see something like:
with self.canvas as c:
c.color = Color(1, 1, 0)
c.shape = Ellipse()
In this case the with context wouldn't really be doing anything. If you want to explicitly manipulate the canvas you can do it directly without a context manager, e.g. self.canvas.add(Color(1, 1, 0)).
That said, the way you've written this may indicate a misunderstanding: a canvas doesn't have a specific colour as you've indicated with c.color, rather it's a list of instructions to apply in order. There could be many Color instructions, with different numbers of other instructions (e.g. representing different shapes) in between.

Gtk Popover Menu is not using the default padding

I created a GtkPopoverMenu and added some text buttons to it, but I can't get it to follow the same padding as other popovers, like the one in Nautilus.
The default style classes are being applied, and GtkInspector shows the same padding values as the popover in Nautilus, but, visually, the padding isn't there.
Here is the relevant part of the code:
pbox = Gtk.Box(orientation = Gtk.Orientation.VERTICAL)
popover.add(pbox)
one = Gtk.ModelButton.new()
one.set_label("Button One")
pbox.pack_start(one, False, False, 0)
two = Gtk.ModelButton.new()
two.set_label("Button Two")
pbox.pack_start(two, False, False, 0)
three = Gtk.ModelButton.new()
three.set_label("Button Three")
pbox.pack_start(three, False, False, 0)
And how it looks vs how the one in Nautilus looks: Image
And the full code: Code
Am I missing something here?
Nautilus uses a combination of margin and padding for its Popover.
I hope the screenshot demonstrates it. The first is the Popover as it is with your code. The second one has a margin but as you can see, the selection directly touches the text. Therefore the third Popover has margin and padding.
The margin can be set with widget.set_property('margin', 10) and the padding with a css file.

Images in wx.ListControl are cut off

I have a wx.ListCtrl in REPORT mode and i use an image list to display icons which are 50x50 pixels with SetItemColumnImage. The problem now is that the text I display in the column right of the icon is less than 50 pixels high and the parts of the icons that are higher than the text are cut off.
Is there a way to tell ListCtrl to adjust the row height to the height of the icons? Last refuge would be to change the fontsize of the text, but there should be a better way.
Update:
Here is some of my code:
self.list = util.ListCtrl(nb, style=wx.LC_REPORT|
wx.LC_SINGLE_SEL|wx.LC_NO_HEADER|wx.LC_ALIGN_LEFT)
self.list.InsertColumn(0, 'Avatar', width=-1)
self.list.InsertColumn(1, 'Name', width=-1)
self.list.SetColumnWidth(0, 50)
self.imagelist = wx.ImageList(50, 50, 255, 20)
self.list.SetImageList(self.imagelist, wx.IMAGE_LIST_SMALL)
i = 0
for user in self.users:
self.list.Append(['', user['name']])
if user['avatar']:
bitmap = wx.BitmapFromImage(user['avatar'])
imageidx = self.imagelist.Add(bitmap)
self.list.SetItemColumnImage(i, 0, imageidx)
i += 1
When I remove the LC_REPORT flag the images are completely visible but they are all displayed in one row and the names aren't visible anymore.
Since the images are 50x50, I don't think they qualify as "small" any more. Try using the wx.IMAGE_LIST_NORMAL instead of wx.IMAGE_LIST_SMALL. I can't find anything about manually setting row height, so I'm guessing that's not possible. However, I did find a bug report on this topic that says it was resolved in wx2.9. Are you using 2.9?
Alternatively, you could use the UltimateListCtrl which is pure Python and if it doesn't have that ability, you can probably get it patched quickly as the author is very responsive.
Took me a couple cups of coffee to figure it out.
The call to ImageList.Add should precede ListCtrl.Append (or ListCtrl.InsertItem) in order for the ListCtrl to change the height of its rows according to the height of images in ImageList.
So instead of
for user in self.users:
self.list.Append(['', user['name']])
if user['avatar']:
bitmap = wx.BitmapFromImage(user['avatar'])
imageidx = self.imagelist.Add(bitmap)
self.list.SetItemColumnImage(i, 0, imageidx)
You should go with something like this
for user in self.users:
if user['avatar']:
bitmap = wx.BitmapFromImage(user['avatar'])
imageidx = self.imagelist.Add(bitmap)
self.list.Append(['', user['name']])
if user['avatar']:
self.list.SetItemColumnImage(i, 0, imageidx)
Which looks ugly, until you implement a default avatar:
def_avatar = 'default_avatar.jpg'
for user in self.users:
bitmap = wx.BitmapFromImage(user['avatar'] if user['avatar'] else def_avatar)
imageidx = self.imagelist.Add(bitmap)
self.list.Append(['', user['name']])
self.list.SetItemColumnImage(i, 0, imageidx)

How to merge (join) two wx.bitmap using wxpython?

I have one wx.emptybitmap (1) and one wx.bitmap (2). I want to merge(join) them..
I want to create a single wx.bitmap that consists on the wx.emptybitmap (1) on the top and wx.bitmap (2) on the bottom.
How can I do that?
Thanks in advance! :D
After a lot of web searching here it is :)
The code is something like that!
empty = wx.EmptyBitmap(parent.imageWidth,12+parent.imageHeight)
dc = wx.MemoryDC()
dc.SelectObject(empty)
dc.SetTextForeground(parent.colorFont)
dc.SetPen(wx.Pen('WHITE', 1))
dc.DrawLine(0, 3, parent.imageWidth, 3)
dc.DrawLine(0, 6, parent.imageWidth, 6)
dc.DrawLine(0, 9, parent.imageWidth, 9)
dc.DrawBitmap(imageSmall[len(imageSmall)-1], 0, 12, True)
dc.SelectObject(wx.NullBitmap)
wx.StaticBitmap.__init__(self, parent, id, bitmap=empty, pos=(position[0], position[1]), size=(parent.imageWidth, parent.imageHeight))
You could always use PIL, it has a function to do this. Save the image in memory and convert it into an wx.Bitmap.

Categories