Search code examples
pythonpyqtpyqt5maya

Display QTreeWidget branch lines within Maya (PyQt5)?


To start, I'm using PySide2 within Maya which is pretty much the same as PyQt5.

I'm creating a ui with a pretty simple QTreeWidget. I guess Maya's default style choices do not show the branch lines connecting all of the tree items and I would like them, so I've been trying to add them back in (without success).

Here's some relevant code showing what I've tried:

import PySide2.QtCore as QtCore
import PySide2.QtGui as QtGui
import PySide2.QtWidgets as QtWidgets

# I'm defining the stylesheet string outside of my function (which is why it's all caps)
#
STYLESHEET = '''QTreeWidget {border:none;} 
QTreeWidget::item {height: 20px;}

QTreeView {
    alternate-background-color: rgba(35,35,35,255);
    background: rgba(45,45,45,255);}

QTreeView::branch:has-siblings:!adjoins-item {
    border-image: url(vline.png) 0;}

QTreeView::branch:has-siblings:adjoins-item {
    border-image: url(branch-more.png) 0;}

QTreeView::branch:!has-children:!has-siblings:adjoins-item {
    border-image: url(branch-end.png) 0;}

QTreeView::branch:has-children:!has-siblings:closed,
QTreeView::branch:closed:has-children:has-siblings {
    border-image: none;
    image: url(branch-closed.png);}

QTreeView::branch:open:has-children:!has-siblings,
QTreeView::branch:open:has-children:has-siblings {
    border-image: none;
    image: url(branch-open.png);}'''

# and an excerpt from where I'm creating my QTreeWidget (inside a function)
#
tree_widget = QtWidgets.QTreeWidget()
tree_widget.setFocusPolicy(QtCore.Qt.NoFocus)
tree_widget.setAlternatingRowColors(True)
tree_widget.setStyleSheet(STYLESHEET)
tree_widget.setUniformRowHeights(True)
tree_widget.setItemsExpandable(False)
tree_widget.setHeaderHidden(True)

I also have a recursive function that goes through a nested dictionary to add QTreeWidgetItems to the tree widget, which I can show if you need... After the items are added I use tree_widget.expandAll() to open them up.

I snagged all of the QTreeView::branch stylesheet items from the QTreeView section on this site: http://doc.qt.io/qt-5/stylesheet-examples.html and since my tree will always be fully expanded, I probably don't need the closed items or the arrows, but I was trying to just get the defaults there first before trying to modify it...

Anyway, No lines (or arrows) are getting displayed... After I added the branch items to the stylesheet string, the arrows that were there from Maya's default style disappeared as well (which is fine because I didn't want them anyway). I know that at least part of the stylesheet is working since the atlernating color lines do work correctly.

So I guess the real question is how do I get those images to show? I thought they might somehow be inherently stored in the PySide2/PyQt5 libraries, but I'm guessing not since nothing is showing... How do I go about explicitly telling the stylesheet where the images are stored so they can be used?

Thanks!


Solution

  • As it turns out, the answer is easier than I suspected.... The issue I was having is related to how windows directories are separated with \ instead of / ugh...

    You can very easily put a relative or whole path to an image file in the stylesheet string and it will locate and use the file UNLESS you use a windows path (even if you escape out the backslashes).

    So url(C:\path\to\image.png) and url(C:\\path\\to\\image.png) do not work.

    But url(C:/path/to/image.png) actually does work - and fortunately finds the file even though the directory separators are incorrect for windows...

    I ended up saving and modifying the branch images from the stylesheet examples website in my first post. Once I had them saved in a location near the file I'm writing my ui tool in, I then generated their respective file paths and replaced the backslashes with forward slashes - which would look something like this: VLINE = os.path.join(path, 'vline.png').replace('\\', '/'). Then I used string formatting to insert them into my stylesheet string and it worked.