HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

To do tree application with undo/redo functionality

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
applicationwithredofunctionalityundotree

Problem

I am making a to-do tree application (Earlybird) in Python that will show checkable tasks/subtasks in a tree view. It includes higher-level groups of tasks grouped into blocks (e.g., Work block, Home block) that do not have checkboxes.

It looks like this:

This is is my first application using Python, and object-oriented programming in general. I am usually a Matlab programmer. Hence, feedback on any level of what I've done would be very helpful. I'm about to put the application on Github, and add a ton of features, so now is the perfect time to throw some dynamite at it.

The application has two main classes:

  • EarlybirdTree: the core tree view. This is subclassed from QTreeView, and defines basic methods (loading and saving files, adding edited items to the undo stack, etc)..



  • EarlybirdMain: a simple wrapper for EarlybirdTree objects. This is subclassed from QMainWindow, and allows the user to interact with the tree's methods using menus and toolbars.



The following code includes the above two py files, as well as an earlybird data file (testFile.eb). I store the data in json format. Each main function also adds a separate view of the undostack, just for convenience. Note to keep this from blowing up, I haven't included the functionality for adding/removing items and many other bells and whistles.

earlybirdTree.py

```
# -- coding: utf-8 --
"""
earlybirdTree.py
Defines the EarlyBirdTree class, a QTreeView subclass that displays a
custom QStandardItemModel as a simple to-do tree. The data is saved
as a custom json file.
"""

import sys
import os
import json
from PySide import QtGui, QtCore

class StandardItemModel(QtGui.QStandardItemModel):
'''Items will emit this signal when edited'''
itemDataChanged = QtCore.Signal(object, object, object, object)

class StandardItem(QtGui.QStandardItem):
''''Subclass QStandardItem to reimplement setData to emit itemDataChanged'''
def setData(self, newValue, role=QtCore.Qt.Us

Solution

From your answer to my comment, I will drop the intended Python 3 paragraph (even though there are some goodies you may like in the most recent versions, such as the new pathlib that supersedes the old os.path module) and go straight to the main point:

Qt Designer is the way to go

Writing user interface code is something that nobody likes to do. You could seriously save a good amount of lines of code by designing your main UI in Qt Designer and using pyuic4 or pyside-uic to generate the boring code so that you can concentrate on the Model and Control part of the code.

Internationalization

While it may not be important, it doesn't cost more than a few self.tr() in order to tell which strings may be translated, even if you don't set up any translation for now. But if one day you want to translate everything, you will be glad not to have to reread your entire project to know which strings need to be translated. That said, many of the strings to be translated are automatically marked as such in the code generated by Qt Designer.

Consistency is the key

When reading the following piece of code:

def __init__(self, parent=None, filename = None):
    QtGui.QTreeView.__init__(self, parent=None)


Two things strike me:

-
Was your intention to forward parent to QTreeView.__init__? If so, I fear that it is not what's being done right here.

-
The way declare default values for parameter in inconsistent style-wise. I bet that it is an oversight though since most of your code seems consistent when it comes to the style. If we follow the PEP8 (I guess we should), we should drop the spaces around the = for default parameters:

def __init__(self, parent=None, filename=None):
    QtGui.QTreeView.__init__(self, parent)

Code Snippets

def __init__(self, parent=None, filename = None):
    QtGui.QTreeView.__init__(self, parent=None)
def __init__(self, parent=None, filename=None):
    QtGui.QTreeView.__init__(self, parent)

Context

StackExchange Code Review Q#88065, answer score: 5

Revisions (0)

No revisions yet.