I have a MainUI, that has a few buttons, line-edits and checkboxes. Most of the widgets I have set with a given state - e.g. all checkboxes are checked by default, and all line-edit fields have a default value of "1.0".
Currently I have a pushbutton called "reset everything". As its name implies, any changes made in these checkboxes or line-edit fields will be reverted to be checked and have a value of "1.0".
One way I can think of resetting the values, is by creating a function where I have to re-type the variable names of the affected widgets, along with their default state - which is similar to what I did when I created them. But I don't think this is a practical method.
My question here is: what is the best way for me to store the default values and then revert them?
So far I have created a class that contains the creation of the main ui:
class MainUI(QtGui.QDialog):
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent)
self.setWindowTitle('UI MANAGER')
self.setModal(False)
self.init_main_ui()
self.resize(QtCore.QSize(600, 350))
# UI-Configurations
def init_main_ui(self):
self.check1 = QtGui.QCheckBox("chk_box1")
self.check2 = QtGui.QCheckBox("chk_box2")
self.check3 = QtGui.QCheckBox("chk_box3")
self.check1.setChecked(True)
self.check2.setChecked(True)
self.check3.setChecked(True)
self.max_label = QtGui.QLabel("MIN Val")
self.max_input = QtGui.QLineEdit("0.0")
self.min_label = QtGui.QLabel("MAX Val")
self.min_input = QtGui.QLineEdit("1.0")
...
The simplest approach would be to refactor your existing code so that the initial values are set by a separate method:
class MainUI(QtGui.QDialog):
...
def init_main_ui(self):
self.check1 = QtGui.QCheckBox("chk_box1")
self.check2 = QtGui.QCheckBox("chk_box2")
self.check3 = QtGui.QCheckBox("chk_box3")
self.max_label = QtGui.QLabel("MIN Val")
self.max_input = QtGui.QLineEdit()
self.min_label = QtGui.QLabel("MAX Val")
self.min_input = QtGui.QLineEdit()
...
self.reset_main_ui()
def reset_main_ui(self):
self.check1.setChecked(True)
self.check2.setChecked(True)
self.check3.setChecked(True)
self.max_input.setText("0.0")
self.min_input.setText("1.0")
...
Related
I'm working on a small project and I'm having issues retrieving the values stored in combo boxes. The program has a "plus" button that creates additional boxes beneath the existing ones. They are created by calling a "create" function that makes a new instance of the ComboBox class, where the box is created and put onto the screen. A separate "submit" function is then supposed to loop through and retrieve all of the box values and store them in a list. My main flaw is that I used data in the variable names, but I have no clue how else to do this in this scenario. Does anyone have an alternative solution?
(there are some off screen variables that are show used here as parameters, but there are definitely not the source of the issue)
class ComboBox:
def __init__(self, master, counter, fields):
self.master = master
self.counter = counter
self.fields = fields
self.field_box = ttk.Combobox(width=20)
self.field_box["values"] = fields
self.field_box.grid(row=counter + 1, column=0, pady=5)
def get_value(self):
value = self.field_box.get()
return value
def create():
global entry_counter
name = "loop"+str(entry_counter-1)
name = ComboBox(window, entry_counter, fields)
values.append(name.get_value())
entry_counter += 1
def submit():
for i in range(1, entry_counter):
name = "loop" + str(entry_counter-1)
values.append(name.get_value())
For example, if I created 2 boxes and selected the options "test1" and "test2" I would want the my values list to contain ["test1, "test2"]
Not sure I understand the question right, but I guess you are asking about how to loop throw all instances of ComboBox. You can just create an global array, append new instance into it in create() method:
comboboxes = []
def create():
...
comboboxes.append(new_instance)
def submit():
for combobox in comboboxes:
...
You're on the right track with .get(). I believe your solution is that your get_value function also needs an event parameter:
def get_value(self, event):
value = self.field_box.get()
return value
See the following:
Getting the selected value from combobox in Tkinter
Retrieving and using a tkinter combobox selection
So I'm working on an embedded user editable table in tkinter. I'd like to give the PlateLayout class a custom set of rows instead of the default 1,2,3...
import Tkinter as tk
from tkintertable.Tables import TableCanvas
class PlateLayout:
def __init__(self, parent):
self.parent = parent
def make_frame(self):
self.the_frame = tk.Frame(self.parent)
self.the_frame.pack()
def make_table(self):
self.the_table = TableCanvas(self.the_frame, rows=8, cols=12)
self.the_table.createTableFrame()
def make_all(self):
self.make_frame()
self.make_table()
root_win = tk.Tk()
app = PlateLayout(root_win)
app.make_all()
root_win.mainloop()
I've seen screen shots of renamed columns, but haven't found a reference as to how to do this programmatically.
This is referenced from https://code.google.com/p/tkintertable/wiki/Usage#Change_column_labels
A quick change to your code will let you set custom labels;
....
def make_table(self):
self.the_table = TableCanvas(self.the_frame, rows=8, cols=12)
# Lets peek at the current labels, delete in production
print self.the_table.model.columnlabels
self.the_table.model.columnlabels['1'] = "Custom Col"
self.the_table.createTableFrame()
....
I'm trying to update my UI via a variable in another python file. Both are in there own class. Both saved in a folder called: System.
As I don't want to re-execute UI, I can't simply import the file.
My question: how does one change a variable from another class in another file, without re-executing?
toolsUI.py
class toolsUI:
def __init__(self):
# Store UI elements in a dictionary
self.UIElements = {}
if cmds.window("UI", exists=True):
cmds.deleteUI("UI")
self.UIElements["window"]=cmds.window("UI", width=200, height=600, title="UI")
self.createColumn() # Create Column
# Display window
cmds.showWindow(self.UIElements ["window"])
def createColumn(self):
self.UIElements["column"] = cmds.columnLayout(adj=True, rs=3)
self.UIElements["frameLayout"] = cmds.frameLayout(height=columnHeight, collapsable=False, borderVisible=True, label="To Change Label")
maintenance.py
class maintenance:
def __init__(self):
changeLabel = "Label is Changed"
self.changeLabelColumn(changeLabel) # Change Label Column
def changeLabelColumn(self, changeLabel):
import System.toolsUI as toolsUI """<--- probably not a good idea"""
cmds.frameLayout(toolsUI.UIElements["frameLayout"], edit=True, label=changeLabel)
The right way to do this afaict would be to create an object of the toolsUI type, and then operate on that instead.
import System
class maintenance:
def __init__(self):
changeLabel = "Label is Changed"
self.ui = System.toolsUI() # create a new object
self.changeLabelColumn(changeLabel)
def changeLabelColumn(self, changeLabel):
cmds.frameLayout(
self.ui.UIElements["frameLayout"], # use the object instead
edit=True,
label=changeLabel)
this way you can have multiple toolsUI objects that don't interfere with each other.
How can I bind a checkbox to a string such that when the checkbox is checked/unchecked, the value of the string changes? I have this (with CheckAll as my checkbox):
class MyWindow(Window):
def __init__(self):
wpf.LoadComponent(self, 'BioApp1.xaml')
openDialog = SequenceFileOperations()
self.Sequences = openDialog.Open()
object = MyObjects(self.Sequences)
self.CheckAll.DataContext = object
self.IDLabel.DataContext = object
class MyObjects(object):
def __init__(self, Sequences):
self.CurrentSeq = Sequences[0]
self.ID = self.CurrentSeq.ID
and
<Label Height="28" HorizontalAlignment="Left" Margin="152,221,0,0" VerticalAlignment="Top" Width="98" Name="IDLabel" Content="{Binding Path=ID}"/>
I want that when the checkbox is unchecked, the label should display the sequence ID, but when it is checked, it should simply display “All”. For this I need to change the ID property of CurrentSeq to “All”. How do I do that by data binding? Is there any other way I can do this?
EDIT: I feel really stupid but I just can’t get this to work. I have been trying to follow the suggestion about using getter/setter but I guess I don’t know enough. Before doing anything more complicated, I simply want to make a button disabled when I tick the checkbox and enable it when I uncheck it. This is what I wrote:
class MyWindow(Window):
def __init__(self):
wpf.LoadComponent(self, 'App1.xaml')
object = BindingClass(self.Check, self.PreviousBtn)
self.PreviousBtn.DataContext = object
class BindingClass(object):
def __init__(self, Check, PreviousBtn):
self.Check = Check
self.PreviousBtn = PreviousBtn
def GetEnabledConverter(self):
if self.CheckAll.IsChecked:
return self.PreviousBtn.IsEnabled
def SetEnabledConverter(self):
if self.CheckAll.IsChecked:
self.PreviousBtn.IsEnabled = False
else:
self.PreviousBtn.IsEnabled = True
EnabledConverter = property(GetEnabledConverter, SetEnabledConverter)
And:
<Button Content="Previous" IsEnabled="{Binding Path=EnabledConverter}" />
Unfortunately there is no error but no effect either. The code does not do anything. Would really appreciate if you could help me out with this.
EDIT2: Using the notify_property, I tried this:
class MyWindow(Window):
def __init__(self):
wpf.LoadComponent(self, 'Test.xaml')
c = Converters(self.check1, self.Button)
self.Button.DataContext = c
class Converters(NotifyPropertyChangedBase):
def __init__(self, check, button):
super(Converters, self).__init__()
self.Check = check
self.Button = button
#notify_property
def ButtonEnabled(self):
return self.Button.IsEnabled
#ButtonEnabled.setter
def ButtonEnabled(self):
if self.Check.IsChecked:
self.Button.IsEnabled = False
else:
self.Button.IsEnabled = True
Still the same result: no effect. I just cannot understand where the problem is.
I would use Converter.
Edit:
You can implement converter in Python:
class BoolToVisibilityConverter(IValueConverter):
def Convert(self, value, targetType, parameter, culture):
return Visibility.Visible if value != val else Visibility.Collapsed
Last time I worked with WPF in IronPython, you could not use it directly in .xaml. I am not sure whether it has improved in 2.7.
Another possibility is to add another property which does the conversion (converted_ID) in its setter/getter. Thinking more about it, I would do rather this, because the code is in one place.
Edit 2:
Make sure, you are using notify_property instead of classic Python property.
I'm rewriting this post to clarify some things and provide a full class definition for the Virtual List I'm having trouble with. The class is defined like so:
from wx import ListCtrl, LC_REPORT, LC_VIRTUAL, LC_HRULES, LC_VRULES, \
EVT_LIST_COL_CLICK, EVT_LIST_CACHE_HINT, EVT_LIST_COL_RIGHT_CLICK, \
ImageList, IMAGE_LIST_SMALL, Menu, MenuItem, NewId, ITEM_CHECK, Frame, \
EVT_MENU
class VirtualList(ListCtrl):
def __init__(self, parent, datasource = None,
style = LC_REPORT | LC_VIRTUAL | LC_HRULES | LC_VRULES):
ListCtrl.__init__(self, parent, style = style)
self.columns = []
self.il = ImageList(16, 16)
self.Bind(EVT_LIST_CACHE_HINT, self.CheckCache)
self.Bind(EVT_LIST_COL_CLICK, self.OnSort)
if datasource is not None:
self.datasource = datasource
self.Bind(EVT_LIST_COL_RIGHT_CLICK, self.ShowAvailableColumns)
self.datasource.list = self
self.Populate()
def SetDatasource(self, datasource):
self.datasource = datasource
def CheckCache(self, event):
self.datasource.UpdateCache(event.GetCacheFrom(), event.GetCacheTo())
def OnGetItemText(self, item, col):
return self.datasource.GetItem(item, self.columns[col])
def OnGetItemImage(self, item):
return self.datasource.GetImg(item)
def OnSort(self, event):
self.datasource.SortByColumn(self.columns[event.Column])
self.Refresh()
def UpdateCount(self):
self.SetItemCount(self.datasource.GetCount())
def Populate(self):
self.UpdateCount()
self.datasource.MakeImgList(self.il)
self.SetImageList(self.il, IMAGE_LIST_SMALL)
self.ShowColumns()
def ShowColumns(self):
for col, (text, visible) in enumerate(self.datasource.GetColumnHeaders()):
if visible:
self.columns.append(text)
self.InsertColumn(col, text, width = -2)
def Filter(self, filter):
self.datasource.Filter(filter)
self.UpdateCount()
self.Refresh()
def ShowAvailableColumns(self, evt):
colMenu = Menu()
self.id2item = {}
for idx, (text, visible) in enumerate(self.datasource.columns):
id = NewId()
self.id2item[id] = (idx, visible, text)
item = MenuItem(colMenu, id, text, kind = ITEM_CHECK)
colMenu.AppendItem(item)
EVT_MENU(colMenu, id, self.ColumnToggle)
item.Check(visible)
Frame(self, -1).PopupMenu(colMenu)
colMenu.Destroy()
def ColumnToggle(self, evt):
toggled = self.id2item[evt.GetId()]
if toggled[1]:
idx = self.columns.index(toggled[2])
self.datasource.columns[toggled[0]] = (self.datasource.columns[toggled[0]][0], False)
self.DeleteColumn(idx)
self.columns.pop(idx)
else:
self.datasource.columns[toggled[0]] = (self.datasource.columns[toggled[0]][0], True)
idx = self.datasource.GetColumnHeaders().index((toggled[2], True))
self.columns.insert(idx, toggled[2])
self.InsertColumn(idx, toggled[2], width = -2)
self.datasource.SaveColumns()
I've added functions that allow for Column Toggling which facilitate my description of the issue I'm encountering. On the 3rd instance of this class in my application the Column at Index 1 will not display String values. Integer values are displayed properly. If I add print statements to my OnGetItemText method the values show up in my console properly. This behavior is not present in the first two instances of this class, and my class does not contain any type checking code with respect to value display.
It was suggested by someone on the wxPython users' group that I create a standalone sample that demonstrates this issue if I can. I'm working on that, but have not yet had time to create a sample that does not rely on database access. Any suggestions or advice would be most appreciated. I'm tearing my hair out on this one.
Are you building on the wxPython demo code for virtual list controls? There are a couple of bookkeeping things you need to do, like set the ItemCount property.
One comment about your OnGetItemText method: Since there's no other return statement, it will return None if data is None, so your test has no effect.
How about return data or "" instead?
There's a problem with the native object in Windows. If GetImg returns None instead of -1 the list has a problem with column 1 for some reason. That from Robin over on the Google Group post for this issue.