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.
Related
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.
Is there a way to change TextBox text color at any moment? I tried Google already; my question looks too trivial, but I am still at a loss.
TextBox methods:
: dir(matplotlib.widgets.TextBox)
Out[63]:
[
...
'active',
'begin_typing',
'connect_event',
'disconnect',
'disconnect_events',
'drawon',
'eventson',
'get_active',
'ignore',
'on_submit',
'on_text_change',
'position_cursor',
'set_active',
'set_val',
'stop_typing']
AxesWidget superclass methods:
: dir(matplotlib.widgets.AxesWidget)
Out[64]:
[
...
'active',
'connect_event',
'disconnect_events',
'drawon',
'eventson',
'get_active',
'ignore',
'set_active']
Nothing suggestive. At least, to my eye.
A partial answer only - without knowing the fuller application it isn't obvious whether this helps you. There are 2 pieces of text that you can change the color of: the label and the edit box. Below shows how to change each, once.
import matplotlib.widgets
import matplotlib.pyplot as plt
plt.figure(1)
ax = plt.subplot(111)
tb = matplotlib.widgets.TextBox(ax, "Name:", initial="Jane Doe")
tb.label.set_color('red') # label color
tb.text_disp.set_color('blue') # text inside the edit box
If you just want the label text to be different, that persists. But whenever the text inside the edit box (text_disp) is changed, it will be in black again.
This is because widget recreates the text
(by removing and then re-generating and it will be in black again.
The source for the text create method does not have any arguments that the user could modify (color, font size/weight etc) or include as a TextBox instance attribute.
You could write your own subclass that overrides this method. Or perhaps simply setting it after text has been entered is enough for you?
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).
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)
I'm automatically generating a PDF-file with Platypus that has dynamic content.
This means that it might happen that the length of the text content (which is directly at the bottom of the pdf-file) may vary.
However, it might happen that a page break is done in cases where the content is too long.
This is because i use a "static" spacer:
s = Spacer(width=0, height=23.5*cm)
as i always want to have only one page, I somehow need to dynamically set the height of the Spacer, so that the "rest" of the space that is left on the page is taken by the Spacer as its height.
Now, how do i get the "rest" of height that is left on my page?
I sniffed around in the reportlab library a bit and found the following:
Basically, I decided to use a frame into which the flowables will be printed. f._aH returns the height of the Frame (we could also calculate this by hand). Subtracting the heights of the other two flowables, which we get through wrap, we get the remaining height which is the height of the Spacer.
elements.append(Flowable1)
elements.append(Flowable2)
c = Canvas(path)
f = Frame(fx, fy,fw,fh,showBoundary=0)
# compute the available height for the spacer
sheight = f._aH - (Flowable1.wrap(f._aW,f._aH)[1] + Flowable2.wrap(f._aW,f._aH)[1])
# create spacer
s = Spacer(width=0, height=sheight)
# insert the spacer between the two flowables
elements.insert(1,s)
# create a frame from the list of elements
f.addFromList(elements,c)
c.save()
tested and works fine.
As far as i can see you want to have footer, right?
Then you should do it like:
def _laterPages(canvas, doc):
canvas.drawImage(os.path.join(settings.PROJECT_ROOT, 'templates/documents/pics/footer.png'), left_margin, bottom_margin - 0.5*cm, frame_width, 0.5*cm)
doc = BaseDocTemplate(filename,showBoundary=False)
doc.multiBuild(flowble elements, _firstPage, _laterPages)