[PySide] simple QTableView example

Frank Rueter | OHUfx frank at ohufx.com
Mon Oct 14 15:30:31 CEST 2013


WOW. that is more than I was aiming for, thank you so much!!
I will take a look at your code soon (am just about to hop on a plane 
for a 30 hour flight).
I wrote a standard approach without animation and the default MVC 
classes which is working as well, and now was about to embark on 
researching the fancy way, so I have a great start now.

Thanks heaps again!
frank

On 14/10/13 2:22 PM, Aaron Richiger wrote:
> Hello Frank!
>
> I just implemented the approach I told you yesterday (without 
> QTableView, QListView, etc because you wanted animations). You can see 
> the code of the working app in the attachment, it's in a classical MVC 
> setup. Because dealing with databases is a bit more work when not 
> using QSqlTableModel, I save and load tasks and user settings between 
> sessions using pickle. I did not spend much time on a nice design, 
> it's just to give you some sample code in case you really want the 
> animations. With some more lines of code, you can pimp the design 
> according to your wishes.
>
> Have a nice day!
> Aaron
>
>
>
> Am 13.10.2013 13:54, schrieb Frank Rueter | OHUfx:
>> sweet, that was my hunch, just didn't want to barge in the wrong 
>> direction.
>> I will keep doing some more basics as per the suggestions from you 
>> and the others before embarking on this one, but have an idea now how 
>> to tackle it.
>>
>> Cheers,
>> frank
>>
>> On 13/10/13 1:52 PM, Aaron Richiger wrote:
>>> Hello Frank!
>>>
>>> You're welcome. I will send you more details later (do not have too 
>>> much time for the moment). But just to give you the direction:
>>>
>>> If the animation is a must-have, I would not go the way with 
>>> QTableView nor the way with QListView or QTreeView. Without 
>>> animation, those are perfect, but if you really want the fancy 
>>> animations, I would do it like this:
>>>
>>> - Implement a widget to show a TODO-Item
>>> - Show them absolutely positioned one after the other
>>> - Implement buttons for "Add new", "Sort", "Filter"
>>> - In case of sort or filtering: calculate new position for each 
>>> item, animate it to new position using QParallelAnimationGroup
>>>
>>> See you later!
>>> Aaron
>>>
>>>
>>>
>>>
>>>
>>> Am 13.10.2013 13:18, schrieb Frank Rueter | OHUfx:
>>>> Great, thanks Tibold and Aaron! That all makes sense.
>>>>
>>>> Incidentally I do have planned a bit more than just the standard 
>>>> table UI but thought I'd leave that for when I'm more comfortable 
>>>> with the basic concepts again.
>>>> So am keen to test all suggested approaches and have a feeling I 
>>>> might have to go with a custom solution as I want some animation to 
>>>> happen when sorting (each line moving to it's new position) - but 
>>>> that's for later, for now I will stick to the basics.
>>>>
>>>> Aaron, when trying the setItemDelegateForColumn (sorry, how could I 
>>>> not have seen this one before) things work fine but I have to cast 
>>>> the incoming data to int() explicitly in side the setEditorData. 
>>>> The setModelData method seems to automatically cast the integer 
>>>> back to a string. Is this the right way to do it?
>>>>
>>>>     def setEditorData(self, spinBox, index):
>>>>         value = index.model().data(index)
>>>>         spinBox.setValue(*int(value)*)*# cast string to int*
>>>>
>>>>     def setModelData(self, spinBox, model, index):
>>>>         spinBox.interpretText()
>>>>         value = spinBox.value()
>>>>         model.setData(index, *value*)*# no need to cast int back to 
>>>> string?*
>>>>
>>>>
>>>> Looking ahead: If I want to make the rows/tasks animate to their 
>>>> new positions upon sorting, can I re-implement the paint methods 
>>>> of, say, a QAbstractItemView or do I have to go back further and do 
>>>> more manual work?
>>>> I need to stick to the standard PySide package for this for various 
>>>> reasons.
>>>>
>>>> Cheers and thanks again Tibold, Aaron and Sebastian, you are a 
>>>> great help as usual!
>>>>
>>>> frank
>>>>
>>>>
>>>>
>>>> On 13/10/13 12:39 AM, Aaron Richiger wrote:
>>>>> Hello!
>>>>>
>>>>> Tibolds approach would work (and could result in a nicer UI). Both 
>>>>> solutions are possible, some thoughts about the QTableView approach:
>>>>>
>>>>> - your app smells like a future database app. QTableView is in 
>>>>> advantage then, because by using QSqlTableModel, you get all the 
>>>>> mapping betwenn the db and the model for free.
>>>>> - By using QTableView, sorting, filtering etc. is already included 
>>>>> and if your table has manymany rows, it will be much faster than 
>>>>> any self implemented filtering/sorting algorithm. But as long, as 
>>>>> your todo list doesn't have thousands of entries (and I hope so 
>>>>> for you:-), performance isn't an argument.
>>>>>
>>>>> Changes to your code to have the spinbox in the middle column only:
>>>>>
>>>>>         priorityDelegate = SpinBoxDelegate(tableView)
>>>>>         tableView.setItemDelegateForColumn(1, priorityDelegate)
>>>>>
>>>>> Like this, the first column remains "text-editable", and for the 
>>>>> last column with the checkbox, you don't even necessarily have to 
>>>>> implement a new delegate, reimplementing .flags(), setData() and 
>>>>> data() methods of your model is enough (but if you want a pure 
>>>>> checkbox without a label next to it, you have to write your own 
>>>>> delegate, I could send you the code).
>>>>>
>>>>> Feel free to choose what ever way you want, both are perfectly 
>>>>> doable, having advantages where the other variant has disadvantages...
>>>>>
>>>>> Cheers
>>>>> Aaron
>>>>>
>>>>>
>>>>> Am 13.10.2013 00:06, schrieb Tibold Kandrai:
>>>>>> If you ask me personally, I wouldn't use QTableWidget. Look into 
>>>>>> QTreeView or QListWidget.
>>>>>> I think they are more suitable for such tasks and are easier to 
>>>>>> handle.
>>>>>> With QTreeView you can use QItemDelegate, to create a special 
>>>>>> rendering.
>>>>>> With QListWidget you can simply add a widget per row and inside 
>>>>>> the widget you can put whatever.
>>>>>> ATM I'm in the middle of a 2000 km road trip so I can't rally 
>>>>>> provide you sample's, but if you need help next week I'm glad to 
>>>>>> give you samples how to use these widgets.
>>>>>> Cheers,
>>>>>> Tibold Kandrai
>>>>>> *From:* Frank Rueter | OHUfx
>>>>>> *Sent:* ?Saturday?, ?12? ?October? ?2013 ?22?:?49
>>>>>> *To:* Tibold Kandrai
>>>>>> *Cc:* pyside at qt-project.org
>>>>>> Is this the best way to do it though? I.e. having one item per 
>>>>>> cell? s there another way at all?
>>>>>> I'm still a bit lost in the model/view design and can't find the 
>>>>>> answer online.
>>>>>>
>>>>>> I'm simply trying to have each row represent a "task" with a 
>>>>>> title/description (string), a status (boolean) and a priority 
>>>>>> (integer). For the integer I need a spin box and for the boolean 
>>>>>> I need a checkbox. The examples I found online all seem to be 
>>>>>> doing something slightly different and often use different ways 
>>>>>> which makes matters more confusing.
>>>>>>
>>>>>> Here is what I have at the moment:
>>>>>> http://pastebin.com/H3GD0xVB
>>>>>>
>>>>>> The "status" and "priority" values don't display currnelty as I 
>>>>>> haven't figured out how to properly assign a delegate to just 
>>>>>> those cells. At the top I tried to define a n item delegete for a 
>>>>>> spin box but I'm not sure how to properly assign it.
>>>>>>
>>>>>> Do I have to make the delegate draw different widgets (spin box / 
>>>>>> checkbox) depending on data type, or can/should I use a different 
>>>>>> delegate for each cell?
>>>>>>
>>>>>> I'm sure the answer is right in front of me, could you please 
>>>>>> help one more time please?!
>>>>>>
>>>>>> Cheers,
>>>>>> frank
>>>>>>
>>>>>>
>>>>>> On 11/10/13 4:00 PM, Tibold Kandrai wrote:
>>>>>>
>>>>>>     If you mean to use a QStandardItem per cell then yes.
>>>>>>     Also for storing values that you want to display, use the
>>>>>>     Qt.DisplayRole as role.
>>>>>>
>>>>>>     Cheers,
>>>>>>     Tibold Kandrai
>>>>>>     ------------------------------------------------------------------------
>>>>>>     From: Frank Rueter | OHUfx <mailto:frank at ohufx.com>
>>>>>>     Sent: ?11/?10/?2013 14:35
>>>>>>     To: Tibold Kandrai <mailto:kandraitibold at gmail.com>
>>>>>>     Cc: pyside at qt-project.org <mailto:pyside at qt-project.org>
>>>>>>     Subject: Re: [PySide] simple QTableView example
>>>>>>
>>>>>>     one more silly question if I may:
>>>>>>     So if I have a task like this:
>>>>>>             newTask = {'title':'new task', 'priority':1,
>>>>>>     'status':False}
>>>>>>
>>>>>>     and need to store the data in one row in the model I should
>>>>>>     use three different items, one for each value, right?!
>>>>>>
>>>>>>     e.g.:
>>>>>>
>>>>>>             newTask = {'title':'new task', 'priority':1,
>>>>>>     'status':False}
>>>>>>             row = self.model.rowCount()
>>>>>>             for column, attr in enumerate(['title', 'priority',
>>>>>>     'status']):
>>>>>>                 newItem = QtGui.QStandardItem(newTask[attr])
>>>>>>                 self.model.setItem(row, column, newItem)
>>>>>>
>>>>>>     then juggle delegates or widgets to use a spin box for the
>>>>>>     integer and a checkbox for the boolean...
>>>>>>
>>>>>>     Thanks for the help!
>>>>>>
>>>>>>     Cheers,
>>>>>>     frank
>>>>>>
>>>>>>     On 10/10/13 11:44 PM, Tibold Kandrai wrote:
>>>>>>
>>>>>>         Hey,
>>>>>>         I'm not sure I understand the problem correctly.
>>>>>>         If you want to store data in a cell or a QStandardItem,
>>>>>>         then you need to use setData() and data().
>>>>>>         Generally you shouldn't need to subclass QStandardItem or
>>>>>>         QStandardItemModel.
>>>>>>         Here is an example how:
>>>>>>         # Define roles
>>>>>>         FINISHED_ROLE = QtCore.Qt.UserRole + 1
>>>>>>         PRIORITY_ROLE = QtCore.Qt.UserRole + 2
>>>>>>         # Create model
>>>>>>         model = QtGui.QStandardItemModel()
>>>>>>         item = QtGui.QStandarItem()
>>>>>>         model.appendRow(item)
>>>>>>         item_index = item.index()
>>>>>>         # Store data using the item
>>>>>>         item.setData(finished, FINISHED_ROLE)
>>>>>>         item.setData(priority, PRIORITY_ROLE)
>>>>>>         # Store data using the model
>>>>>>         model.setData(item_index, finished, FINISHED_ROLE)
>>>>>>         model.setData(item_index, priority, PRIORITY_ROLE)
>>>>>>         # Retrieve data using the item
>>>>>>         finished = item.data(FINISHED_ROLE)
>>>>>>         priority = item.data(PRIORITY_ROLE)
>>>>>>         # Retrieve data using the model
>>>>>>         finished = model.data(item_index, FINISHED_ROLE)
>>>>>>         priority = model.data(item_index, PRIORITY_ROLE)
>>>>>>         In some cases like click event handlers, you have the
>>>>>>         model and the item index, there it's easier to use the
>>>>>>         model methods instead of finding the item and then
>>>>>>         getting the data. ?
>>>>>>         Hope it helps.
>>>>>>         Cheers,
>>>>>>         Tibold
>>>>>>         *From:* Frank Rueter | OHUfx
>>>>>>         *Sent:* ?2013? ?October? ?10?, ?Thursday ?19?:?37
>>>>>>         *To:* pyside at qt-project.org
>>>>>>         After looking at some more examples I think my approach
>>>>>>         of storing multiple values in one item is fundamentally
>>>>>>         flawed.
>>>>>>         Instead I should be using one item per cell and assign
>>>>>>         the respective data, right?!
>>>>>>
>>>>>>         I shall re-write the example accordingly, sorry for the
>>>>>>         noise.
>>>>>>
>>>>>>         frank
>>>>>>
>>>>>>         On 10/10/13 6:34 PM, Frank Rueter | OHUfx wrote:
>>>>>>
>>>>>>             I meant QTableView not QStandardTableView :/
>>>>>>
>>>>>>             On 10/10/13 6:33 PM, Frank Rueter | OHUfx wrote:
>>>>>>
>>>>>>                 Hi all,
>>>>>>
>>>>>>                 after a bit of a break from PySide I am trying to
>>>>>>                 wrap my head around the model/view stuff again
>>>>>>                 and am trying to understand how a very simple
>>>>>>                 example would work where a QStandarItem has
>>>>>>                 properties "title", "priority" and "finished"
>>>>>>                 which are displayed via a QStandardTableView.
>>>>>>
>>>>>>                 I am struggling with understanding how to
>>>>>>                 properly display the above three properties in
>>>>>>                 the table's columns. I tried setting the data()
>>>>>>                 method on the model like this:
>>>>>>
>>>>>>                 /    def data(self, index,
>>>>>>                 role=QtCore.Qt.DisplayRole)://
>>>>>>                 //        '''Return data based on index and role'''//
>>>>>>                 //        item = self.itemFromIndex(index)//
>>>>>>                 //        if index.column() == 0://
>>>>>>                 //            return item.title//
>>>>>>                 //        elif index.column() == 1://
>>>>>>                 //            return item.finished//
>>>>>>                 //        elif index.column() == 2://
>>>>>>                 //            return item.priority/
>>>>>>
>>>>>>                 but for some reason it errors saying item does
>>>>>>                 not have attribute "finished" even though my item
>>>>>>                 object s declared like this:
>>>>>>
>>>>>>                 /class TaskItem(QtGui.QStandardItem)://
>>>>>>                 //    '''Item to hold a task for the todo list'''//
>>>>>>                 ////
>>>>>>                 //    def __init__(self, title, finished=False,
>>>>>>                 priority=1)://
>>>>>>                 //        super(TaskItem, self).__init__(title)//
>>>>>>                 //        self.title = title//
>>>>>>                 //        self.finished = finished//
>>>>>>                 //        self.priority = priority/
>>>>>>
>>>>>>
>>>>>>                 When printing the item's attributes via dir() I
>>>>>>                 see that, when the model is populated, the last
>>>>>>                 item it attempts to call is not my custom item
>>>>>>                 object, but something else with less attributes
>>>>>>                 and methods. Clearly there is something I haven't
>>>>>>                 quite understood about this process.
>>>>>>
>>>>>>                 Also, if I use the models data() method as
>>>>>>                 pointed out above, I get checkboxes in the cells
>>>>>>                 which I don't want at this stage.
>>>>>>
>>>>>>                 Can somebody please help me understand where I go
>>>>>>                 wrong?
>>>>>>                 Attached is the whole test code.
>>>>>>
>>>>>>                 Cheers,
>>>>>>                 frank
>>>>>>
>>>>>>                 P.S.: I am aware that the controller code
>>>>>>                 shouldn't necessarily live in the QWidget's
>>>>>>                 methods, this is just for testing which I will
>>>>>>                 clean up once I get how it all connects again
>>>>>>
>>>>>>
>>>>>>                 _______________________________________________
>>>>>>                 PySide mailing list
>>>>>>                 PySide at qt-project.org
>>>>>>                 http://lists.qt-project.org/mailman/listinfo/pyside
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>             _______________________________________________
>>>>>>             PySide mailing list
>>>>>>             PySide at qt-project.org
>>>>>>             http://lists.qt-project.org/mailman/listinfo/pyside
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> PySide mailing list
>>>>>> PySide at qt-project.org
>>>>>> http://lists.qt-project.org/mailman/listinfo/pyside
>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> PySide mailing list
>>>>> PySide at qt-project.org
>>>>> http://lists.qt-project.org/mailman/listinfo/pyside
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> PySide mailing list
>>>> PySide at qt-project.org
>>>> http://lists.qt-project.org/mailman/listinfo/pyside
>>>
>>>
>>>
>>> _______________________________________________
>>> PySide mailing list
>>> PySide at qt-project.org
>>> http://lists.qt-project.org/mailman/listinfo/pyside
>>
>>
>>
>> _______________________________________________
>> PySide mailing list
>> PySide at qt-project.org
>> http://lists.qt-project.org/mailman/listinfo/pyside
>
>
>
> _______________________________________________
> PySide mailing list
> PySide at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/pyside

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/pyside/attachments/20131014/d74f9755/attachment.html>


More information about the PySide mailing list