Search code examples
pythonhtmlimagetooltippyside

PySide: Add images to tooltips


I'm building a tool that lists files in a directory. When you hover over each file it shows a tooltip displaying the date and who made the file. I'd also like an image to accompany this data.

Is it possible to insert an image into a tooltip? For each item in the QTreeView I'd like a specific image and text to popup. If it can't be done with tooltips are there other alternatives?

from PySide import QtCore, QtGui
from shiboken import wrapInstance
import maya.OpenMayaUI as mui

def get_parent():
    ptr = mui.MQtUtil.mainWindow()
    return wrapInstance( long( ptr ), QtGui.QWidget )   

############################################        
''' Classes '''
############################################
class Main_Window( QtGui.QDialog ):
    def __init__( self, parent=get_parent() ):
        super( Main_Window, self ).__init__( parent )

        self.create_gui()
        self.create_layout()
        self.create_connections()
        self.get_contents()

    #--------------------------------------------------------------------
    def create_gui( self ):
        self.tv_model=MyModel()
        self.tv_file_list = File_List( self )

    #--------------------------------------------------------------------
    def create_layout( self ):
        self.main_layout = QtGui.QVBoxLayout( self )
        self.main_layout.addWidget( self.tv_file_list )
        self.setLayout( self.main_layout )

    #--------------------------------------------------------------------
    def get_contents(self):
        self.tv_model.clear()
        self.tv_model.setHorizontalHeaderLabels(["name","date"])
        contents=["path1","path2"]
        for path in contents:
            date = self.get_date(path)
            self.add_file(path,date)
        self.tv_file_list.setColumnWidth(0, 150)

    #--------------------------------------------------------------------
    def add_file(self, name, date):
        name = QtGui.QStandardItem(name)
        name.setToolTip(name.text())
        name.setIcon(self.style().standardIcon(QtGui.QStyle.SP_DirOpenIcon))
        date = QtGui.QStandardItem(date)
        self.tv_model.appendRow([name, date])

    #--------------------------------------------------------------------
    def get_date(self, path):
        return "a date"

    #--------------------------------------------------------------------
    def create_connections( self ):
        self.tv_file_list.clicked.connect( self.on_click )

    # slots --------------------------------------------------------------
    def on_click(self, item ):
        index = self.tv_file_list.selectedIndexes()[0]
        item = self.tv_model.itemFromIndex(index).text()
        print item

############################################
class MyModel(QtGui.QStandardItemModel):
    def __init__(self, parent=None):
        super(MyModel, self).__init__(parent)

    #--------------------------------------------------------------------
    def flags(self, index):
        flag = QtCore.Qt.ItemIsEnabled
        if index.isValid():
            flag |= QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable 
        return flag

############################################
class File_List( QtGui.QTreeView ):
    ''' Create the file filters '''
    def __init__( self, mainUIWindow, parent=get_parent() ):
        super( File_List, self ).__init__( parent )

        self.setModel(mainUIWindow.tv_model)
        self.setIndentation(0)
        self.setColumnWidth(0,500)
        self.setFocusPolicy(QtCore.Qt.NoFocus)
        self.setStyleSheet("QToolTip { color: rgb(170,170,170); background-color: rgb(20,20,20); border: 1px rgb(20,20,20); }")


############################################
if __name__ == "__main__":
    # workaround for a bug in maya
    try:
        tree_view_ui.close()
        tree_view_ui.deleteLater()
    except:
        pass

    tree_view_ui = Main_Window()
    tree_view_ui.show()

    try:
        tree_view_ui.show()
    except:
        tree_view_ui.close()
        tree_view_ui.deleteLater()

SOLUTION: Thanks to ekhumoro for the quick and easy solution! Here's the updated code and a link to some HTML basics that helped me format the tooltip:

from PySide import QtCore, QtGui from shiboken import wrapInstance import maya.OpenMayaUI as mui

def get_parent():
    ptr = mui.MQtUtil.mainWindow()
    return wrapInstance( long( ptr ), QtGui.QWidget )   

############################################        
''' Classes '''
############################################
class Main_Window( QtGui.QDialog ):
    def __init__( self, parent=get_parent() ):
        super( Main_Window, self ).__init__( parent )

        self.create_gui()
        self.create_layout()
        self.create_connections()
        self.get_contents()

    #--------------------------------------------------------------------
    def create_gui( self ):
        self.tv_model=MyModel()
        self.tv_file_list = File_List( self )

    #--------------------------------------------------------------------
    def create_layout( self ):
        self.main_layout = QtGui.QVBoxLayout( self )
        self.main_layout.addWidget( self.tv_file_list )
        self.setLayout( self.main_layout )

    #--------------------------------------------------------------------
    def get_contents(self):
        self.tv_model.clear()
        self.tv_model.setHorizontalHeaderLabels(["name","date"])
        contents=["path1","path2"]
        for path in contents:
            date = self.get_date(path)
            self.add_file(path,date)
        self.tv_file_list.setColumnWidth(0, 150)

    #--------------------------------------------------------------------
    def add_file(self, name, date):
        name = QtGui.QStandardItem(name)
        user_text = "Me"
        image_path = "C:/windows/temp/image_01.png"
        name.setToolTip('<b>{0}</b><br><img src="{1}">'.format(user_text, image_path))
        name.setIcon(self.style().standardIcon(QtGui.QStyle.SP_DirOpenIcon))
        date = QtGui.QStandardItem(date)
        self.tv_model.appendRow([name, date])

    #--------------------------------------------------------------------
    def get_date(self, path):
        return "a date"

    #--------------------------------------------------------------------
    def create_connections( self ):
        self.tv_file_list.clicked.connect( self.on_click )

    # slots --------------------------------------------------------------
    def on_click(self, item ):
        index = self.tv_file_list.selectedIndexes()[0]
        item = self.tv_model.itemFromIndex(index).text()
        print item

############################################
class MyModel(QtGui.QStandardItemModel):
    def __init__(self, parent=None):
        super(MyModel, self).__init__(parent)

    #--------------------------------------------------------------------
    def flags(self, index):
        flag = QtCore.Qt.ItemIsEnabled
        if index.isValid():
            flag |= QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable 
        return flag

############################################
class File_List( QtGui.QTreeView ):
    ''' Create the file filters '''
    def __init__( self, mainUIWindow, parent=get_parent() ):
        super( File_List, self ).__init__( parent )

        self.setModel(mainUIWindow.tv_model)
        self.setIndentation(0)
        self.setColumnWidth(0,500)
        self.setFocusPolicy(QtCore.Qt.NoFocus)
        self.setStyleSheet("QToolTip { color: rgb(170,170,170); background-color: rgb(20,20,20); border: 1px rgb(20,20,20); }")


############################################
if __name__ == "__main__":
    # workaround for a bug in maya
    try:
        tree_view_ui.close()
        tree_view_ui.deleteLater()
    except:
        pass

    tree_view_ui = Main_Window()
    tree_view_ui.show()

    try:
        tree_view_ui.show()
    except:
        tree_view_ui.close()
        tree_view_ui.deleteLater()

Solution

  • Tooltips accept rich-text, which means you can use any markup that is part of the Supported HTML Subset. This includes an img tag, so all you need is something like:

        item.setToolTip('<b>%s</b><br><img src="%s">' % (filename, iconpath))