Python Gtk3 controlling button size - python

The button size should be controlled by packing HBox in VBox but my two buttons still have size depending on text:
first=Gtk.VBox()
second=Gtk.HBox()
third=Gtk.VBox()
fourth=Gtk.HBox()
but1=Gtk.Button(label="any title")
first.pack_start(second,False,False,0)
third.pack_start(fourth,False,False,0)
first.pack_start(but1,False,False,0)
self.data_wp="title of label"
self.label_data=Gtk.Label(label=self.data_wp)
Gtk.Widget.set_size_request(but1,85,15)
but2=Gtk.Button(label=self.data_wp)
Gtk.Container.add(but2,self.label_data)
Gtk.Widget.set_size_request(but2,85,15)
What am I doing wrong? I add button title from label but it shoudn't be the problem, and I tried to set title directly on button - nothing changed. I tried to use only one set of VBox,HBox, but it gave no effect too.

I think the problem here is that you're trying to resize the button using the set_size_request() method of the Gtk.Widget. But set_size_request() only set the minimum size of the widget, so it can still be larger.
I don't know if there is a method to resize the button, but there are the properties width-request and height-request of the Gtk.Widget that you can use.
In your code, it would be:
bt1.set_property("width-request", 85)
bt1.set_property("height-request", 15)

Related

pyqt: how to use scroll area that contains an outsized label [duplicate]

I want to overlay two widgets in QtDesigner:
There is the big QTextBrowser, and below in the down right corner should be a non-interactiv label that I am going to use as a drag-grip to resize the window (the main widget is frameless so I need to implement it).
Usually this label will sit below the QTextBrowser, which leaves on the left of the grip-label a lot of unused space. So I want to put the grip-label above the QTextBrowser. I want to achieve this in QtDesigner. But the code would look like:
QHBoxLayout *layout = new QHBoxLayout(videoWidget);
QLabel *overlayWidget = new QLabel();
overlay->setAlignment(Qt::AlignCenter);
overlay->setText("Overlaid Text");
layout->addWidget(overlay);
Or as I already did in python:
self.textedit = QTextBrowser(self);
...
gripImage=QLabel(self.textedit);
There the part between the brackets is the parent widget.
That's how it looks right now, but this is not what I want:
This is usually simplest to achieve by using QGridLayout. It allows widgets to occupy the same grid cells. For this particular problem, a 1x1 grid is enough.
Steps to try it out with designer:
Create new form, plain Widget for simplicity
Add a text edit to it (drag and drop from Widget Box), and from Object Inspector you should see it becomes child of the root widget
Add a label to it (drag and drop from Widget Box), and from Object Inspector you should see it becomes child of the root widget
Right click on the root widget (easiest in the Object Inspector), and from the bottom of context menu, select Lay out > - Lay out in Grid
Right click on the label, and from Layout alignment > set it aligned to the corner you want
Done. Here's what it looks like in my Designer:
Now adapt above to your real form.
Ok, it appears achieving above with Designer is hard, and perhaps a bit a matter of luck of doing things just right... Designer just doesn't support doing what you want, it seems.
For clarity this is a complete source code:
QGridLayout *layout = new QGridLayout(widget);
QTextBrowser *textBrowser = new QTextBrowser();
QLabel *label = new QLabel();
label->setText("Overlaid Text");
//label gets positioned above textBrowser and is an overlay
layout->addWidget(textBrowser, 0, 0, Qt::AlignLeft | Qt::AlignTop);
layout->addWidget(label, 0, 0, Qt::AlignRight | Qt::AlignBottom);
I had the same problem but I did not manage to add Overlapping widgets in QtDesigner. Instead, I had to create the overlapping one dynamically after initializing my MainWindow.
I've got two widgets:
dataset_tableWidget (tableWidget)
spinner_dataset_tableWidget (QtWaitingSpinner)
and I wanted to make spinner_dataset_tableWidget spin over the dataset_tableWidget.
After initializing the MainWindow you can do:
#Crating QtWaitingSpinners dinamically and positioning it over the tableWidgets
dataset_tableWidget = QtWaitingSpinner(dataset_tableWidget)
dataset_tableWidget.setSizePolicy(dataset_tableWidget.sizePolicy())

Resize the widgets if the window is resized if they were displayed with place

I have a program that has about 12 widgets on the root window and all of them are placed using .place(x,y).
The problem is that when the window is resized, everything stays in the same position and does not adjust to the window. Can this be fixed?
Yes, it is possible.
You can set the values of relwidth and relheight options to what you want (between 0.0 and 1.0.) by using place_configure() function:
your_widget_1.place_configure(relheight=1.0, relwidth=1.0)
Alternatively, you can set the options I mentioned directly during the process of placing the widgets using place() function. Example:
your_widget_1.place(bordermode=OUTSIDE,relheight=1.0, relwidth=1.0)

How do I change the built-in button labels on a gtk.Assistant?

I want to change the label of the 'Apply' button of a gtk.Assistant to 'Start'. I can't find the corresponding gtk.Button widget in the Assistant instance.
Here's some basic code for a two-page Assistant:
import gtk
a = gtk.Assistant()
page = gtk.CheckButton("Something optional")
a.append_page(page)
a.set_page_type(page, gtk.ASSISTANT_PAGE_CONTENT)
a.set_page_title(page, "Make decisions")
a.set_page_complete(page, True)
page = gtk.Label("Alright, let's build some foo.")
a.append_page(page)
a.set_page_type(page, gtk.ASSISTANT_PAGE_CONFIRM)
a.set_page_title(page, "Confirm")
a.set_page_complete(page, True)
a.connect('delete-event', gtk.main_quit)
a.connect('close', gtk.main_quit)
a.show_all()
gtk.main()
On the final page you'll see the 'Apply' button. I want to change that text to 'Start'.
gtk.Assistant.children() and .get_children() return the list of page widgets.
gtk.Assistant.get_child() returns None.
gtk.Assistant.get_action_area() isn't a method.
Here's a link to the documentation.: http://www.pygtk.org/docs/pygtk/class-gtkassistant.html
How do I find the gtk.Button I'm interested in?
I managed to find a solution while experimenting with workarounds.
gtk.Assistant overrides the gtk.Container.get_children() method with something that returns the list of pages, but it is still in fact the parent of a gtk.HBox() which contains the buttons for 'Next', 'Apply', 'Cancel', etc.
The method gtk.Assistant.add_action_widget() adds a widget to the so-called "action area". It turns out this is the HBox containing the relevant buttons. The following function will produce a reference to the HBox:
def get_buttons_hbox(assistant):
# temporarily add a widget to the action area and get its parent
label = gtk.Label('')
assistant.add_action_widget(label)
hbox = label.get_parent()
hbox.remove(label)
return hbox
Then the buttons are retrieved using get_buttons_hbox(a).get_children().
for child in get_buttons_hbox(a).get_children():
print child.get_label()
This prints:
gtk-goto-last
gtk-go-back
gtk-go-forward
gtk-apply
gtk-cancel
gtk-close
So the following code solves the problem (using get_buttons_hbox() defined above):
for child in get_buttons_hbox(a).get_children():
label = child.get_label()
if label == 'gtk-apply':
child.set_label('Start')
I'm not sure this will be possible with pygtk. If you switch to GObject Introspection with python you can set a fully custom action area. From the Gtk3 GtkAssistant documentation:
If you have a case that doesn't quite fit in GtkAssistants way of
handling buttons, you can use the GTK_ASSISTANT_PAGE_CUSTOM page type
and handle buttons yourself.
and
GTK_ASSISTANT_PAGE_CUSTOM Used for when other page types are not
appropriate. No buttons will be shown, and the application must add
its own buttons through gtk_assistant_add_action_widget().

Controling button/hbox sizes in gtk

I am writing an app in python using getk and I've come across a problem. I am using an hbox to hold the buttons that go on my tool bar (new, open, save, etc) but the hbox seems to be expanding to take up a particular portion of the screen and the buttons are doing so as well making them really tall and ugly. How do I get them to stay at adecent size? I have already tried setting the expand and fill values to false and I can't find any methods to control the size of ether a button or an hbox. Here is the code for my new button:
img = gtk.Image()
img.set_from_stock(gtk.STOCK_NEW,gtk.ICON_SIZE_SMALL_TOOLBAR)
newButt = gtk.Button()
newButt.set_image(img)
newButt.show()
self.hBox4.pack_start(newButt, False, False, 0)
You need to contain the entire HBox in a VBox, as follows:
main = gtk.VBox(False)
...
main.pack_start(self.hbox4, False)
The reason for this is that gtk allows for window resizing, so it doesn't allocate fixed heights and widths. By using a VBox, you are telling Gtk that I want the HBox to take up just as much space as it needs at the top of my window.
Hope that helps.
Child widgets will assume the allocation size that they parent widgets can give. You should set the size of the hbox or the button.
See here the size_request method of PyGTK to get more information.

How to Create a Multiline Button

I'm trying to create a multiline button with PyGTK. I have a label added to my subclass of gtk.Button, but I'm having trouble sizing the label to the button. If the label makes it's own size, there is no text wrapping even with label.set_line_wrap(True) because the label simply resizes beyond the bounds of the button. I would set the size of the label to that of the button, but unless I explicitly set the size of the button using set_size_request, I haven't been able to find out how big the button is (it's packed in a table).
Any suggestions?
In general, this is not possible with GTK+, because there is no stage where widgets "negotiate" sizes. Instead, widgets report their required size and after that container allocate some areas (normally, equal to or larger than required). In GTK+ 3 there will be width-for-height negotiation, so if your button (rather its label) is anyway going to be allocated several lines, it will be able to request less width and wrap its text.
In 2.x the best you can do is probably use width_chars property of gtk.Label:
import gtk
window = gtk.Window ()
align = gtk.Alignment (0.5, 0.5)
button = gtk.Button ('a very long, possibly multiline text')
label = button.child
label.props.wrap = True
label.props.width_chars = 20
window.set_default_size (500, 500)
window.connect ('destroy', lambda *ignored: gtk.main_quit ())
window.add (align)
align.add (button)
window.show_all ()
gtk.main ()
I found that in Python 3.4 GTK+3 all you need to do is add a \n where you want the break. It doesn't autowrap but you can have multiline labels for button objects. For example,
self.button = Gtk.Button(label="A lotta text \n and a lotta more.")

Categories

Resources