Group Gtk.RadioToolButtons? - python

I've been trying for days to find a way to group RadioToolButtons in pygobject without success. There is no *.RadioToolButton.join_group(*) method like RadioButtons.
Here is what I've been trying:
## Toolbar
self.mainWindow.mainBox.mainToolbar = Gtk.Toolbar()
self.mainWindow.mainBox.mainToolbar.get_style_context().add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR)
self.mainWindow.mainBox.mainToolbar.set_style(Gtk.ToolbarStyle.BOTH)
self.mainWindow.mainBox.mainToolbar.radioGroup = list() # *.radioGroup = [] Does not work either.
## Left toolbar separator
self.mainWindow.mainBox.mainToolbar.leftSeparator = Gtk.SeparatorToolItem(draw = False)
self.mainWindow.mainBox.mainToolbar.leftSeparator.set_expand(True)
## Overview toggle button
self.mainWindow.mainBox.mainToolbar.overviewRadio = Gtk.RadioToolButton(Gtk.STOCK_HOME)
self.mainWindow.mainBox.mainToolbar.overviewRadio.set_group(self.mainWindow.mainBox.mainToolbar.radioGroup)
self.mainWindow.mainBox.mainToolbar.overviewRadio.set_is_important(True)
self.mainWindow.mainBox.mainToolbar.overviewRadio.set_label("Overview")
self.mainWindow.mainBox.mainToolbar.overviewRadio.connect("clicked", self.on_overviewRadio_clicked)
self.mainWindow.mainBox.mainToolbar.overviewRadio.set_border_width(4)
## Basic settings toggle button
self.mainWindow.mainBox.mainToolbar.basicRadio = RadioToolButton(Gtk.STOCK_PROPERTIES)
self.mainWindow.mainBox.mainToolbar.basicRadio.set_group(self.mainWindow.mainBox.mainToolbar.radioGroup)
self.mainWindow.mainBox.mainToolbar.basicRadio.set_is_important(True)
self.mainWindow.mainBox.mainToolbar.basicRadio.set_label("Basic")
self.mainWindow.mainBox.mainToolbar.basicRadio.connect("clicked", self.on_basicRadio_clicked)
self.mainWindow.mainBox.mainToolbar.basicRadio.set_border_width(4)
## Right toolbar separator
self.mainWindow.mainBox.mainToolbar.rightSeparator = Gtk.SeparatorToolItem(
draw = False)
self.mainWindow.mainBox.mainToolbar.rightSeparator.set_expand(True)
(Not all of my code - *.show_all() is not the issue)
Here is what I get:
What am I doing wrong? How can I group these two buttons?

Create the second radio button so it's in the first radio button's group using:
Gtk.RadioToolButton.new_with_stock_from_widget(first_button, Gtk.STOCK_PROPERTIES)
PS. Looks like the UI task you are trying to accomplish might be better done with a Notebook?

Related

PyQt5 update QVBoxLayout inside scrollArea

I do have a problem while updating my content on-demand.
My scenario: I want to create a GUI which stores information about some products and it should be displayed via a scroll are. This is working fine, but when I want to update the information like the quantity of my item, the GUI or the layout of my QVBoxLayout does not update the new information on the screen.
My code for the update function:
#pyqtSlot(GroupContent)
def _updateData(self, box: GroupContent) -> None:
prompt = UpdatePrompt(self._conn, box)
prompt.exec()
amount = self._top_layout.count()
for i in range(amount):
tmp = self._top_layout.itemAt(i).widget()
if tmp.id != box.id:
continue
tmp.setTitle(box.title)
tmp.lblPrice.setText(str(box.price))
tmp.lblQuantity.setText(str(box.quantity))
The param box does already get the updated information from a QDialog.
The self._top_layout variable will be created with self._top_layout = QVBoxLayout().
I already tried to call update on the Mainwindow and also on the top layout.
Also tried directly accessing the widget with self._top_layout.itemAt(i).widget().setTitle('test') for example.
If this information is necessary, here is my function to dynamic generate the groupboxes:
def _populate(self, insert: Boolean = False) -> None:
data = self._getDBData(insert)
for row in data:
group_box = GroupContent()
group_box.storage_id.connect(self._updateData)
group_box.id = row.storage_id
group_box.title = row.name
group_box.price = row.price
group_box.quantity = row.quantity
group_box.image = row.image
self._top_layout.addWidget(group_box)

One checkbox controls other checkboxes in Maya with Python

I am making a UI in Maya with Python. My goal is to make the master checkbox be able to control other checkboxes so that when the master checkbox is checked, all the other checkboxes are checked and vice versa. The function is as same as the Game Exporter/Animation Clips section in Maya. You can add multiple clips and use the master checkbox to control all clips. Does anyone know how to do that with Python?
The example (image) of what I want to achieve:
I've tried to use changeCommand, onCommand, and offCommand to edit other checkboxes, but it didn't work.
The code is like this (clipOn is multiple checkboxes, and masterCheckbox is the master checkbox that can control others):
clipOn = cmds.checkBox(label = '')
masterCheckbox = cmds.checkBox(label = '', onCommand = lambda x: cmds.checkBox(clipOn, editable = True, onCommand = True))
It's late and this is untested, but something like the following should work. Maya's 'onCommand'/ 'offCommand' parameters require a string or command to be returned. I used enumerate with list comprehension so that it should return a string for each value as it loops through and edits the checkboxes (rather than a single list). Of course you can always just call a regular function, which is arguably an easier and more straightforward approach.
master = cmds.checkBox(label='All')
check1 = cmds.checkBox(label='One')
check2 = cmds.checkBox(label='Two')
check3 = cmds.checkBox(label='Three')
checkAll = lambda state: [cmds.checkBox(c, edit=1, value=state) for i, c in enumerate([check1,check2,check3])][i]
cmds.checkBox(master, edit=1, onCommand=checkAll(True), offCommand=checkAll(False))
I would have thought:
checkAll = lambda state: cmds.checkBox([check1, check2, check3], edit=1, value=state)
would have worked. But it appears the checkBox command doesn't allow you to pass in multiple objects.
By the way, if you want to edit the 'onCommand' cmds.checkBox(clipOn, editable = True, onCommand = True)), you would pass a new command in not a bool value. Lastly, there is a 'checkBoxGrp' MEL command that allows creating and editing groups of checkboxes, however ultimately, I don't think it does anything different then what you can accomplish with the standard 'checkBox' command.
I would advise something like this :
from functools import partial
clipList = []
def addClip(*args):
newClip = cmds.checkBox(label='clip', p=mainLayout)
global clipList
clipList.append(newClip)
def setAllClips(ckb_master, *args):
value = cmds.checkBox(ckb_master, q=True, v=True)
if clipList:
for clip in clipList:
cmds.checkBox(clip, e=True, v=value)
mainLayout = cmds.columnLayout()
master = cmds.checkBox(label='All', p=mainLayout, cc=partial(setAllClips, master))
addClip()

I knew how to change a grid cell to a combobox by using wxpython GridCellChoiceEditor,but don't know how to bind for this combobox

this is a part of my code.
class AboutRelatedDialog(wx.Dialog):
def __init__(self,parent,list1,list2,list3):
wx.Dialog.__init__(self,parent,-1)
RelatedGrid = gridlib.Grid(self)
RelatedGrid.CreateGrid(sum(list2) + 1,5)
RelatedGrid.SetColLabelSize(1)
RelatedGrid.SetRowLabelSize(1)
RelatedGrid.SetCellSize(0,0,1,2)
RelatedGrid.SetCellAlignment(0,0,wx.ALIGN_CENTRE,wx.ALIGN_CENTRE)
RelatedGrid.SetCellValue(0,0,'label')
RelatedGrid.SetCellAlignment(0,2,wx.ALIGN_CENTRE,wx.ALIGN_CENTRE)
RelatedGrid.SetCellValue(0,2,'datasource')
RelatedGrid.SetCellAlignment(0,3,wx.ALIGN_CENTRE,wx.ALIGN_CENTRE)
RelatedGrid.SetCellValue(0,3,'data')
RelatedGrid.SetCellAlignment(0,4,wx.ALIGN_CENTRE,wx.ALIGN_CENTRE)
RelatedGrid.SetCellValue(0,4,'comment')
templist1 = ms.ExecQuery('SELECT RepGroup FROM RepGroup')
templist2 = []
for i in templist1:
j = i[0]
templist2.append(j)
for index in range(len(list3)):
RelatedGrid.SetCellAlignment(index + 1,1,wx.ALIGN_CENTRE,wx.ALIGN_CENTRE)
RelatedGrid.SetCellValue(index + 1,1,list3[index])
for i in range(sum(list2) + 1):
dbsource = gridlib.GridCellChoiceEditor(templist2)
RelatedGrid.SetCellEditor(i,2,dbsource)
#RelatedGrid.Bind(wx.EVT_CHOICE,self.EvtChoice,dbsource)
def EvtChoice(self,event):
print 1
and my code doesn't work,because i don't know how to bind a event for these combobox.
when i choose a datasource,i want to create another combobox to show the data that get from the RepGroup table in another cell.
so i must know how to get the event when i choose a datasoure.
You can't (easily) bind to the events generated by wxGrid editor controls, but you can handle EVT_GRID_CELL_CHANGED events generated by the grid itself whenever a value of one of its cells changes.

WxPython BoxSizer inside Listbook

I'm trying to use wx.Listbook to implement a settings window with multiple pages. I made the Listbook just fine, but when I started adding items to a page, I ran into a problem. The items are displayed on top of each other, so it's impossible to see everything I'm trying to show.
self.global_settings_frame = wx.Frame(parent=self, title="Global Settings", name="Global Settings")
self.global_settings_listbook = wx.Listbook(parent=self.global_settings_frame, style=wx.LB_LEFT)
self.global_settings_file_window = wx.Panel(parent=self.global_settings_listbook)
self.global_settings_file_box = wx.BoxSizer(orient=wx.VERTICAL)
self.show_full_pathname_checkbox = wx.CheckBox(self.global_settings_file_window, label="Show full pathname")
self.global_settings_file_box.Add(self.show_full_pathname_checkbox, proportion=1)
self.global_default_extension = wx.TextCtrl(self.global_settings_file_window)
self.global_settings_file_box.Add(self.global_default_extension, proportion=1)
self.global_settings_token_window = wx.Panel(parent=self.global_settings_listbook)
self.global_settings_listbook.InsertPage(0, self.global_settings_file_window, "Files")
self.global_settings_listbook.InsertPage(1, self.global_settings_token_window, "Token Defnition")
self.global_settings_frame.Show()
When I comment out the second element, the uncommented part works fine:
self.global_settings_frame = wx.Frame(parent=self, title="Global Settings", name="Global Settings")
self.global_settings_listbook = wx.Listbook(parent=self.global_settings_frame, style=wx.LB_LEFT)
self.global_settings_file_window = wx.Panel(parent=self.global_settings_listbook)
self.global_settings_file_box = wx.BoxSizer(orient=wx.VERTICAL)
self.show_full_pathname_checkbox = wx.CheckBox(self.global_settings_file_window, label="Show full pathname")
self.global_settings_file_box.Add(self.show_full_pathname_checkbox, proportion=1)
self.global_default_extension = wx.TextCtrl(self.global_settings_file_window)
self.global_settings_file_box.Add(self.global_default_extension, proportion=1)
self.global_settings_token_window = wx.Panel(parent=self.global_settings_listbook)
self.global_settings_listbook.InsertPage(0, self.global_settings_file_window, "Files")
self.global_settings_listbook.InsertPage(1, self.global_settings_token_window, "Token Defnition")
self.global_settings_frame.Show()
But I think the BoxSizer isn't working right because when I comment out the previous line (the one adding the CheckBox to the BoxSizer), the display is the same.
I've tried using separate panels for each element and then putting those panels in the BoxSizer, but that also didn't work (I can show you what that looks like if necessary). So it looks like I'm not using the BoxSizer correctly, but I don't understand how I am supposed to use it in this case. What I want is a page of a ListBook that contains a CheckBox and a TextCtrl (for single line text entry). Can you help?
As I can see, you never assign any sizer to your page(s).
You should just do it :
......
self.global_settings_file_box.Add(self.global_default_extension, proportion=1)
self.global_settings_file_window.SetSizer(self.global_settings_file_box)
self.global_settings_token_window = wx.Panel(parent=self.global_settings_listbook)
......
Regards
Xav'

PyGTK: adding text over widgets

I'm developing a GTK app, and would like to print some messages over existing widgets rather than displaying them in the status bar, kind of like the way Mendeley does it when no document is selected:
(as opposed to what is displayed in the right pane when you select a document:)
Should I dynamically create a panel, label, ... with the appropriate message and destroy it when needed, or is there a simpler / better way?
You don't need to destroy the label, even nothing forces you to do so, neither create it dynamically. You could create it when you need it or glade could do it for you. This is a minimal example but, as you notice, both labels are created only once.
import gtk
labels = []
def changeLabel(widget):
l = p.get_children()[1]
p.remove(l)
nl = labels[l is l1]
p.add2(nl)
w = gtk.Window()
w.connect('destroy', lambda w: gtk.main_quit())
p = gtk.HPaned()
w.add(p)
b = gtk.Button('change label')
b.connect('clicked', changeLabel)
p.add1(b)
l1 = gtk.Label('hello world')
l1.show()
p.add2(l1)
l2 = gtk.Label('ciao mondo')
l2.show()
labels = [l1, l2]
which = 0
w.show_all()
gtk.main()

Categories

Resources