fire signal when qtreewidgetitems checkbox state changes - python

I have a simple example here. What I want to happen is when a user changes the toggle state of the 'Checkbox' i want it to set the property value for the CustomTreeWidgetItem's attr.
In this case each CustomTreeWidgetItem has an attr called dataObject which is where I store my class object Family. Family has an attribute enabled which I want this property to reflect the toggle state of the TreeWidgetItems' checkbox.
I have looked around online and have not found a solution yet for this. Most answers were in c++ or they were causing errors. You can test the results by clicking the print button. It should reflect the changes.
Here are the highlighted bits.
Updated:
The linked question does not answer my question. It does not return the value for the checkbox clicked.
What is this code doing in simple terms? And what do i need to modify to make it set the data object to True or False? Currently it returns 0 or 2. I'm not sure if that is tristate or what. Hope someone can explain what is going on.
if column == 0 and role == 10:
My custom tree widget items have the property dataObject. This is where I store my class object Family which has the property enabled in it.
self.dataObject = None
class Family:
def __init__(self, name, members=None, data=None):
self.name = name
self.enabled = True
Hope that helps.
Thanks
all the code
# Imports
# ------------------------------------------------------------------------------
import sys
from PySide import QtGui, QtCore
# Class
# ------------------------------------------------------------------------------
class Family:
def __init__(self, name, members=None, data=None):
self.name = name
self.enabled = True
# Custom Tree Widget
# ------------------------------------------------------------------------------
class TreeNodeItem( QtGui.QTreeWidgetItem ):
def __init__( self, parent, name ):
## Init super class ( QtGui.QTreeWidgetItem )
super( TreeNodeItem, self ).__init__( parent )
# Column 0 - Text:
self.setText( 0, name )
# Tree Node Data
self.dataObject = None
def setData(self, column, role, value):
if column == 0 and role == 10:
self.dataObject.enabled = value
super(TreeNodeItem, self).setData(column, role, value)
# Variables
# ------------------------------------------------------------------------------
Families = [
Family("Smith"),
Family("Michaels"),
Family("Wislon"),
Family("Yoder")
]
# Main
# ------------------------------------------------------------------------------
class Example(QtGui.QWidget):
def __init__(self,):
super(Example, self).__init__()
self.initUI()
def initUI(self):
# formatting
self.resize(400, 400)
self.setWindowTitle("Example")
# widgets
self.printData = QtGui.QPushButton("Print Families Data")
self.itemList = QtGui.QTreeWidget()
self.itemList.setItemsExpandable(True)
self.itemList.setAnimated(True)
self.itemList.setItemsExpandable(True)
self.itemList.setColumnCount(1)
self.itemList.setHeaderLabels(['Families'])
# signals
self.printData.clicked.connect(self.PrintAllData)
# layout - row/column/verticalpan/horizontalspan
self.mainLayout = QtGui.QGridLayout(self)
self.mainLayout.addWidget(self.itemList,0,0)
self.mainLayout.addWidget(self.printData,1,0)
self.center()
self.show()
self.UpdateFamilies()
def center(self):
qr = self.frameGeometry()
cp = QtGui.QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def PrintAllData(self):
for f in Families:
print f.name, f.enabled
def UpdateFamilies(self):
treeWidget = self.itemList
treeWidget.clear()
for f in Families:
# Add Families
treeNode = TreeNodeItem(treeWidget, f.name)
# assign family class object to dataObject attr of treenode
treeNode.dataObject = f
treeNode.setCheckState(0, QtCore.Qt.Checked)
# Main
# ------------------------------------------------------------------------------
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())

The answer was in the linked question (although in C++) Is it possible to create a signal for when a QTreeWidgetItem checkbox is toggled?
Short answer - no, there doesn't appear to be a signal for that checkbox. There are 2 ways to fix this:
1) As in the linked question, you could implement the SetData method and update your data at the same time:
# Custom Tree Widget
# ------------------------------------------------------------------------------
class TreeNodeItem( QtGui.QTreeWidgetItem ):
def __init__( self, parent, name ):
## Init super class ( QtGui.QTreeWidgetItem )
super( TreeNodeItem, self ).__init__( parent )
# Column 0 - Text:
self.setText( 0, name )
# Tree Node Data
self.dataObject = None
def setData(self, column, role, value):
if column == 0 and role == 10:
self.dataObject.enabled = value
super(TreeNodeItem, self).setData(column, role, value)
2) You could also try manually creating a checkbox, connect up it's signal and add it to the TreeNodeItem using QTreeWidget.setItemWidgem

Related

Can a QAction be used for multiple tasks?

I created a tool using Qt Designer, where it has 3 QLineEdits that is catered for translateX, translateY and translateZ.
For each QLineEdit, I have created a context menu that allows me to set a keyframe for one of the above attribute depending on User's choice.
So instead of writing 3 separate functions that catered to each attribute, I thought of 'recycling' them by using 1 method, but I am having issues with it as I am not very sure if it will be possible since I am using a single QAction.
class MyTool(QtGui.QWidget):
def __init__(self, parent=None):
super(MyTool, self).__init__(parent = parent)
# Read off from convert uic file.
self.ui = Ui_MyWidget()
self.ui.setupUi(self)
# translateX
self.ui.xLineEdit.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.ui.xLineEdit.customContextMenuRequested.connect(self.custom_menu)
# translateY
self.ui.yLineEdit.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.ui.yLineEdit.customContextMenuRequested.connect(self.custom_menu)
# translateZ
self.ui.zLineEdit.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.ui.zLineEdit.customContextMenuRequested.connect(self.custom_menu)
self.popMenu = QtGui.QMenu(self)
set_key_action = QtGui.QAction("Set Key at Current Frame", self)
# I am having issues here..
set_key_action.triggered.connect(self.set_key)
self.popMenu.addAction(set_key_action)
...
...
def set_key(self, attr):
# assuming I am trying to effect this locator1 that already exists in the scene
current_item = "|locator1"
cmds.setKeyframe("{0}.{1}".format(current_item, attr))
def custom_menu(self, point):
self.popMenu.exec_(QtGui.QCursor.pos())
Again, because it is only a single QAction and hence I was stumped... Or will it be better for me to stick in using 3 separate functions instead?
The main problem is that when you connect the triggered signal you do not know that QLineEdit is going to be pressed. Where can we know that QLineEdit was pressed? Well, in the method custom_menu since there the method sender() returns the widget that opens its contextual menu, and to transfer it, a property or data is used, so the fine is to compare the property and the QLineEdit:
class MyTool(QtGui.QWidget):
def __init__(self, parent=None):
super(MyTool, self).__init__(parent=parent)
# Read off from convert uic file.
self.ui = Ui_MyWidget()
self.ui.setupUi(self)
for le in (self.ui.xLineEdit, self.ui.yLineEdit, self.ui.zLineEdit):
le.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
le.customContextMenuRequested.connect(self.custom_menu)
self.popMenu = QtGui.QMenu(self)
self.set_key_action = QtGui.QAction("Set Key at Current Frame", self)
self.set_key_action.triggered.connect(self.set_key)
self.popMenu.addAction(self.set_key_action)
def set_key(self):
le = self.set_key_action.property("lineedit")
# or
# le = self.set_key_action.data()
if le is self.ui.xLineEdit:
print("xLineEdit")
elif le is self.ui.yLineEdit:
print("yLineEdit")
elif le is self.ui.zLineEdit:
print("zLineEdit")
def custom_menu(self, p):
if self.sender() is not None:
self.set_key_action.setProperty("lineedit", self.sender())
# or
# self.set_key_action.setData(self.sender())
self.popMenu.exec_(QtGui.QCursor.pos())
Without debug or source code , i can't figure out what is happen here , because in theory all works , so or i can't understand correctly or have some error in other part of code.
class MyTool(QtGui.QWidget):
def __init__(self, parent=None):
super(MyTool, self).__init__(parent = parent)
# Read off from convert uic file.
self.ui = Ui_MyWidget()
self.ui.setupUi(self)
# translateX
self.ui.xLineEdit.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.ui.xLineEdit.customContextMenuRequested.connect(self.custom_menu)
# translateY
self.ui.yLineEdit.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.ui.yLineEdit.customContextMenuRequested.connect(self.custom_menu)
# translateZ
self.ui.zLineEdit.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.ui.zLineEdit.customContextMenuRequested.connect(self.custom_menu)
self.popMenu = QtGui.QMenu(self)
set_key_action = QtGui.QAction("Set Key at Current Frame", self)
**# Assuming that this phase pass !**
set_key_action.triggered.connect(self.set_key)
self.popMenu.addAction(set_key_action)
...
...
def set_key(self, attr):
**# What happen when you debug this block ?**
current_item = "|locator1"
cmds.setKeyframe("{0}.{1}".format(current_item, attr))
def custom_menu(self, point):
self.popMenu.exec_(QtGui.QCursor.pos())

Accessing to QListWidgetItem from widget inside

I'm trying to figure out how I can get the QWidget that I insert into a QListWidget as a QListWidgetItem to be able to access the list it is a part of so that it can do the following:
Increase/decrease it's position in the list
Remove itself from the list
Pass information from it's own class to a function in the main class
My script layout is a main.py which is where the MainWindow class is. The MainWindow uses the class generated from the main ui file. I also have the custom widget which is it's own class.
Example of GUI:
Relevant code snippets:
main.py
from PyQt4.QtGui import QMainWindow, QApplication
from dungeonjournal import Ui_MainWindow
from creature_initiative_object import InitCreatureObject
from os import walk
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(QMainWindow, self).__init__(parent)
self.setupUi(self)
etc......
def AddToInitiative(self):
creature = self.comboBoxSelectCharacter.currentText()
if(creature):
creatureInfo = ''
with open("creatures/"+str(creature)+".creature", "r") as f:
creatureInfo = f.read()
creatureInfo = creatureInfo.split("|")
customWidget = InitCreatureObject()
customWidgetItem = QtGui.QListWidgetItem(self.initiativeList)
customWidgetItem.setSizeHint(QtCore.QSize(400,50))
self.initiativeList.addItem(customWidgetItem)
self.initiativeList.setItemWidget(customWidgetItem, customWidget)
customWidget.setName(creatureInfo[0])
return
creature_initiative_object.py
class Ui_InitCreatureObject(object):
def setupUi(self, InitCreatureObject):
etc...
class InitCreatureObject(QtGui.QWidget, Ui_InitCreatureObject):
def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()):
QtGui.QWidget.__init__(self, parent, f)
self.setupUi(self)
Edit 1:
To clarify again, I need to be able to use the buttons in the widget to modify the position of itself in the list. The list is part of the main ui. The buttons for up arrow, down arrow, Select, and Remove are the one's I'm trying to get to interact with things outside of their class.
The function they call needs to be able to determine which listItem is being called, be able to modify the list.
For example, if I click remove, it then needs to know which item in the list to remove. So it needs to first know what the list is, then it needs to know what item it is. I'm not sure how to access the instance of the widget that is occupying that listitem. I also am not sure how to get that listitem based on a button press from inside that listitem's class.
Edit 2:
Per the first answer I tried to work that into my code.
main.py had the following function added
def RemoveItem(self):
cwidget = self.sender().parent()
item = self.initiativeList.itemAt(cwidget.pos())
row = self.initiativeList.row(item)
self.initiativeList.takeItem(row)
print(row)
creature_initiative_object.py had the following added to the InitCreatureObject class
class InitCreatureObject(QtGui.QWidget, Ui_InitCreatureObject):
def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()):
QtGui.QWidget.__init__(self, parent, f)
self.setupUi(self)
self.mainwidget = main.MainWindow()
self.btnRemove.clicked.connect(self.mainwidget.RemoveItem)
Item is still not being passed. The parent object seems to be right but when I get the row it always says -1.
The strategy to get the QTableWidgetItem is to use the itemAt() method but for this you must know the position of some point within the QTableWidgetItem.
Since the main objective is to get the item when a signal is sent, then the connected slot is used, so I recommend connecting all the signals to that slot. Given the above the following steps are taken:
Get the object that emits the signal through sender().
Get the sender parent() since this will be the custom widget that was added to the QListWidget() along with the item.
Get the position of the custom widget through pos(), this is the position that should be used in the itemAt() method.
Then you get the text of the button or some parameter that tells me the task to know what action you want to do.
The above can be implemented as follows:
def someSlot(self):
p = self.sender().parent()
it = self.lw.itemAt(p.pos())
text = self.sender().text()
if text == "task1":
do task1
elif text == "task2":
do task2
From the above, the following example is proposed:
class CustomWidget(QWidget):
def __init__(self, text, parent=None):
QWidget.__init__(self, parent)
self.setLayout(QHBoxLayout())
self.buttons = []
vb = QVBoxLayout()
self.layout().addLayout(vb)
self.btnTask1 = QPushButton("task1")
self.btnTask2 = QPushButton("task2")
vb.addWidget(self.btnTask1)
vb.addWidget(self.btnTask2)
self.buttons.append(self.btnTask1)
self.buttons.append(self.btnTask2)
self.btnTask3 = QPushButton("task3")
self.btnTask4 = QPushButton("task4")
self.btnTask5 = QPushButton("task5")
self.btnTask6 = QPushButton("task6")
self.layout().addWidget(self.btnTask3)
self.layout().addWidget(self.btnTask4)
self.layout().addWidget(self.btnTask5)
self.layout().addWidget(self.btnTask6)
self.buttons.append(self.btnTask3)
self.buttons.append(self.btnTask4)
self.buttons.append(self.btnTask5)
self.buttons.append(self.btnTask6)
class MainWindow(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self, parent)
self.lw = QListWidget(self)
self.setCentralWidget(self.lw)
for i in range(5):
cw = CustomWidget("{}".format(i))
for btn in cw.buttons:
btn.clicked.connect(self.onClicked)
item = QListWidgetItem(self.lw)
item.setSizeHint(QSize(400, 80))
self.lw.addItem(item)
self.lw.setItemWidget(item, cw)
def onClicked(self):
p = self.sender().parent()
it = self.lw.itemAt(p.pos())
row = self.lw.row(it)
text = self.sender().text()
print("item {}, row {}, btn: {}".format(it, row, text))
#if text == "task1":
# do task1
#elif text == "task2":
# do task2
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
In your Case:
class MainWindow(QMainWindow, Ui_MainWindow):
[...]
def AddToInitiative(self):
[...]
customWidget = InitCreatureObject()
customWidget.btnRemove.clicked.connect(self.RemoveItem)
# ^^^^^
[...]
def RemoveItem(self):
cwidget = self.sender().parent()
item = self.initiativeList.itemAt(cwidget.pos())
row = self.initiativeList.row(item)
self.initiativeList.takeItem(row)
print(row)

Python Inspect module does not find pyqt class

I have found a very nice solution here on this site in order to store gui settings in pyqt5: Python PyQt4 functions to save and restore UI widget values?
The solution is saved in the function guisave.
Now I'm trying to implement this to my code.
The idea is to close my gui with the exitAction button. This fires the closeApp function which fires the guisave function.
The guisave function should save now all my pyqt objects.
The problem is that this does not happen. I'm not sure how I need to assign the ui variable in the guisave function.
As you can see I tried to assign the mainwindow class. But this does not work. I'm also not sure if this works at all or if I need to scan all functions separately since the QEditLine are in the tab2UI function.
import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
import inspect
class mainwindow(QMainWindow):
def __init__(self, parent = None):
super(mainwindow, self).__init__(parent)
self.initUI()
def initUI(self):
exitAction = QAction(QIcon('icon\\exit.png'), 'Exit', self)
exitAction.setShortcut('Ctrl+Q')
exitAction.triggered.connect(qApp.quit)
exitAction.triggered.connect(self.closeApp)
self.toolbar = self.addToolBar('Exit')
self.toolbar.setMovable(False)
self.toolbar.addAction(exitAction)
self.tab_widget = QTabWidget(self) # add tab
self.tab2 = QWidget()
self.tab_widget.addTab(self.tab2, "Tab_2")
self.tab2UI()
self.setCentralWidget(self.tab_widget)
def tab2UI(self):
self.layout = QFormLayout()
self.layout.addRow("Name",QLineEdit())
self.layout.addRow("Address",QLineEdit())
self.tab2.setLayout(self.layout)
def closeApp(self):
guisave()
def guisave():
ui = mainwindow
settings = QSettings('gui.ini', QSettings.IniFormat)
for name, obj in inspect.getmembers(ui):
if isinstance(obj, QComboBox):
name = obj.objectName() # get combobox name
index = obj.currentIndex() # get current index from combobox
text = obj.itemText(index) # get the text for current index
settings.setValue(name, text) # save combobox selection to registry
if isinstance(obj, QLineEdit):
print obj.objectName()
name = obj.objectName()
value = obj.text()
settings.setValue(name, value) # save ui values, so they can be restored next time
print name, value
if isinstance(obj, QCheckBox):
name = obj.objectName()
state = obj.isChecked()
settings.setValue(name, state)
if isinstance(obj, QRadioButton):
name = obj.objectName()
value = obj.isChecked() # get stored value from registry
settings.setValue(name, value)
def main():
app = QApplication(sys.argv)
ex = mainwindow()
ex.setGeometry(100,100,1000,600)
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
The solution that I propose is responsible for saving the states of the QWidgets, but for this you must put a name through the property objectName:
objectName : QString
This property holds the name of this object. You can find an object by name (and type) using findChild(). You can
find a set of objects with findChildren().
Access functions:
QString objectName() const
void setObjectName(const QString &name)
So you should put a name, for example:
self.tab_widget.setObjectName("tabWidget")
We can use the QApplication :: allWidgets () function to get all the widgets of the application, and then we get the properties and save them, the process of restoring is the reverse of the previous one.
def restore(settings):
finfo = QFileInfo(settings.fileName())
if finfo.exists() and finfo.isFile():
for w in qApp.allWidgets():
mo = w.metaObject()
if w.objectName() != "":
for i in range(mo.propertyCount()):
name = mo.property(i).name()
val = settings.value("{}/{}".format(w.objectName(), name), w.property(name))
w.setProperty(name, val)
def save(settings):
for w in qApp.allWidgets():
mo = w.metaObject()
if w.objectName() != "":
for i in range(mo.propertyCount()):
name = mo.property(i).name()
settings.setValue("{}/{}".format(w.objectName(), name), w.property(name))
The complete example is found here

display object lists in pyside QListWidgets using python, binding?

In my main Faction Widget I have a list containing Faction Objects. Each faction has a name and team member names. I'm not sure if binding would be the ideal solution for this. If so I'm not sure how to do binding?
How can I do the following.
1. Display the faction/team names in the left listview?
2. When creating a new team name using the editext, it updating the listview on the left.
3. When a team is selected, it populate the list on the right showing the team member names.
4. when a user inputs a new member name it gets added to the selected team on the left.
current UI
target UI
the code...
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Info goes here...
"""
import sys
import core_models as models
from PySide import QtGui, QtCore
"""
Base class of team which contains 2 properties
name - name of team
members - list of team member names
"""
################################################################################
class Team:
"""
One line description...
other info....
"""
def __init__(self, name, members=None):
self._name = name
if members==None:
self._members = []
#property
def name(self, value):
# add type validation lines here
self._name = value
#property
def members(self, value):
# add type validation lines here
self._members = value
"""
Base widget which contains
label - describes widget
textedit - input field for appending items to list
listview - displays the list of items teams or members
"""
################################################################################
class NameListWidget(QtGui.QWidget):
def __init__(self, title=None):
super(NameListWidget, self).__init__()
self.initUI()
if title!=None:
self.listLabel.setText(title)
def initUI(self):
# formatting
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle("Input List")
# widgets
self.listLabel = QtGui.QLabel("Label")
self.nameInput = QtGui.QLineEdit()
self.nameList = QtGui.QListWidget()
# signals
self.nameInput.returnPressed.connect(self.pressed_return)
# layout
self.mainLayout = QtGui.QVBoxLayout(self)
self.mainLayout.setContentsMargins(0,0,0,0)
self.mainLayout.addWidget(self.listLabel)
self.mainLayout.addWidget(self.nameInput)
self.mainLayout.addWidget(self.nameList)
self.show()
def pressed_return(self):
txt = self.nameInput.text()
# remove leading and trailing whitespaces
txt = txt.strip()
# replace all remaining spaces with underscores
txt = txt.replace (" ", "_")
if (len(txt) >= 1):
self.nameList.addItem(txt)
self.nameInput.clear()
"""
Main team widget contains two instances of the nameList widget
left widget - contains a list of the team names
right widget - contains list of members names for the selected team
"""
################################################################################
class TeamsWidget(QtGui.QWidget):
def __init__(self):
super(TeamsWidget, self).__init__()
self.initUI()
def initUI(self):
# formatting
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle("Teams")
# widgets
self.sportsListWidget = NameListWidget("Teams")
self.memebersListWidget = NameListWidget("Members")
# layout
self.mainLayout = QtGui.QHBoxLayout(self)
self.mainLayout.setSpacing(10)
self.mainLayout.setContentsMargins(10,10,10,10)
self.mainLayout.addWidget(self.sportsListWidget)
self.mainLayout.addWidget(self.memebersListWidget)
self.show()
self.populateUI()
def populateUI(self):
teamsList = ['packers', 'broncos', 'cowboys', 'steelers'];
self.sportsListWidget.nameList.clear()
for i in teamsList:
self.sportsListWidget.nameList.addItem(i)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
ex = TeamsWidget()
sys.exit(app.exec_())
You can do this by utilizing the returnPressed() signal in your NameListWidget widget:
In initUI:
self.nameInput.returnPressed.connect(self.pressed_return)
Then create the pressed_return method, still in your NameListWidget.
def pressed_return(self):
self.nameList.addItem(self.nameInput.text())
self.nameInput.clear()
This adds the current value to your list, and then clears the QLineEdit.

Powerful table widget for a Python GUI

I'd like to program a table-like GUI. Do you know a powerful table widget (for any GUI), which has ready-made functionality like filtering, sorting, editing and alike (as seen in Excel)?
You can use wxGrid - here's some demo code - you need to manage/wire up all the events yourself on the underlying Table. Its a bit complicated to gove an explaination in words, here's some code (mostly based on the wx examples code):
import wx
from wx import EVT_MENU, EVT_CLOSE
import wx.grid as gridlib
from statusclient import JobDataTable, JobDataGrid
app = wx.App()
log = Logger(__name__)
class JobManager(wx.Frame):
def __init__(self, parent, title):
super(JobManager, self).__init__(parent, title=title)
panel = wx.Panel(self, -1)
self.client_id = job_server.register()
log.info('Registered with server as {}'.format(self.client_id))
self.jobs = job_server.get_all_jobs()
grid = self.create_grid(panel, self.jobs)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(grid, 1, wx.ALL|wx.EXPAND)
panel.SetSizer(sizer)
# Bind Close Event
EVT_CLOSE(self, self.exit)
self.Center()
self.Show()
def exit(self, event):
log.info('Unregistering {0} from server...'.format(self.client_id))
job_server.unregister(self.client_id)
job_server.close()
exit()
def create_grid(self, panel, data):
table = JobDataTable(jobs=data)
grid = JobDataGrid(panel)
grid.CreateGrid(len(data), len(data[0].keys()))
grid.SetTable(table)
grid.AutoSize()
grid.AutoSizeColumns(True)
return grid
def main():
frame = JobManager(None, 'Larskhill Job Manager')
app.MainLoop()
if __name__ == '__main__':
job_server = zerorpc.Client()
job_server.connect('tcp://0.0.0.0:4242')
main()
####
ui/client.py
####
import wx
import wx.grid as gridlib
EVEN_ROW_COLOUR = '#CCE6FF'
GRID_LINE_COLOUR = '#ccc'
COLUMNS = {0:('id', 'ID'), 1:('name', 'Name'), 2:('created_at', 'Created'), 3:('status', 'Current Status')}
log = Logger(__name__)
class JobDataTable(gridlib.PyGridTableBase):
"""
A custom wxGrid Table that expects a user supplied data source.
"""
def __init__(self, jobs=None):
gridlib.PyGridTableBase.__init__(self)
self.headerRows = 0
self.jobs = jobs
#-------------------------------------------------------------------------------
# Required methods for the wxPyGridTableBase interface
#-------------------------------------------------------------------------------
def GetNumberRows(self):
return len(self.jobs)
def GetNumberCols(self):
return len(COLUMNS.keys())
#---------------------------------------------------------------------------
# Get/Set values in the table. The Python version of these
# methods can handle any data-type, (as long as the Editor and
# Renderer understands the type too,) not just strings as in the
# C++ version. We load thises directly from the Jobs Data.
#---------------------------------------------------------------------------
def GetValue(self, row, col):
prop, label = COLUMNS.get(col)
#log.debug('Setting cell value')
return self.jobs[row][prop]
def SetValue(self, row, col, value):
pass
#---------------------------------------------------------------------------
# Some optional methods
# Called when the grid needs to display labels
#---------------------------------------------------------------------------
def GetColLabelValue(self, col):
prop, label = COLUMNS.get(col)
return label
#---------------------------------------------------------------------------
# Called to determine the kind of editor/renderer to use by
# default, doesn't necessarily have to be the same type used
# natively by the editor/renderer if they know how to convert.
#---------------------------------------------------------------------------
def GetTypeName(self, row, col):
return gridlib.GRID_VALUE_STRING
#---------------------------------------------------------------------------`
# Called to determine how the data can be fetched and stored by the
# editor and renderer. This allows you to enforce some type-safety
# in the grid.
#---------------------------------------------------------------------------
def CanGetValueAs(self, row, col, typeName):
pass
def CanSetValueAs(self, row, col, typeName):
pass
#---------------------------------------------------------------------------
# Style the table, stripy rows and also highlight changed rows.
#---------------------------------------------------------------------------
def GetAttr(self, row, col, prop):
attr = gridlib.GridCellAttr()
# Odd Even Rows
if row % 2 == 1:
bg_colour = EVEN_ROW_COLOUR
attr.SetBackgroundColour(bg_colour)
return attr
#-------------------------------------------------------------------------------
# Custom Job Grid
#-------------------------------------------------------------------------------
class JobDataGrid(gridlib.Grid):
def __init__(self, parent, size=wx.Size(1000, 500), data_table=None):
self.parent = parent
gridlib.Grid.__init__(self, self.parent, -1) # so grid references a weak reference to the parent
self.SetGridLineColour(GRID_LINE_COLOUR)
self.SetRowLabelSize(0)
self.SetColLabelSize(30)
self.table = JobDataTable()
Give me a shout if it needs clarification.

Categories

Resources