Issue
The tool I'm building uses tooltips to display extra info about a file before you click on it. It would be great if someone could lend some insight into how to accomplish this. I'm about a month into PySide so I'm having trouble deciphering these advanced examples/answers I've found online, so a simple code example with some comments will help me out a lot.
Here's what I have so far. I have no idea what I'm doing when it comes to events, so this is the best I could do with the code examples I have:
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.setMouseTracking(True) # Set tracking
self.create_gui()
self.create_layout()
self.create_connections()
self.get_contents()
self.shapeItems = []
#-------------------------------------------------------------------- # Mouse things
def mouseMoveEvent(self, event):
if (event.buttons() & QtCore.Qt.LeftButton):
self.moveItemTo(event.pos())
#-------------------------------------------------------------------- # Mouse things
def event(self, event):
if event.type() == QtCore.QEvent.ToolTip:
helpEvent = event
index = self.itemAt(helpEvent.pos())
if index != -1:
QtGui.QToolTip.showText(helpEvent.globalPos(), self.shapeItems[index].toolTip())
else:
QtGui.QToolTip.hideText()
event.ignore()
return True
return super(Main_Window, self).event(event)
#--------------------------------------------------------------------
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()
HERE is a post describing how to create instant tooltips, but without any code examples I'm at a loss for how to write this. The documentation wasn't really much of a help either (it really should have simple examples for beginners).
HERE is a code that shows how to implement mouse move events, but I haven't been able to get it to work in my own example above. I keep getting errors that say: "TypeError: super(type, obj): obj must be an instance or subtype of type" and "AttributeError: 'Main_Window' object has no attribute 'itemAt'"
Again, any help or thoughts would be great. Thank you
SOLUTION
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 )
self.tv_file_list.setMouseTracking(True) # Set mouse tracking
#--------------------------------------------------------------------
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 = "me"
name.setToolTip("<b>{0}</b><br><b>{1}</b>".format(name.text(), user) ) # Here's where I set the tooltip
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 )
self.tv_file_list.entered.connect( self.handleItemEntered ) # New connection
# slots --------------------------------------------------------------
def on_click(self, item ):
index = self.tv_file_list.selectedIndexes()[0]
item = self.tv_model.itemFromIndex(index).text()
print item
#--------------------------------------------------------------------
def handleItemEntered(self, index): # New slot
if index.isValid():
QtGui.QToolTip.showText(
QtGui.QCursor.pos(),
index.data(),
self.tv_file_list.viewport(),
self.tv_file_list.visualRect(index)
)
############################################
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
This is much easier to do using the treeview's entered signal. And if you use the overload of showText that takes a rect
argument, QToolTip
will automatically do the rest.
Here's a simple demo:
from PySide import QtCore, QtGui
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
self.view = QtGui.QTreeView(self)
self.view.setMouseTracking(True)
self.view.entered.connect(self.handleItemEntered)
model = QtGui.QStandardItemModel(self)
for text in 'One Two Three Four Five'.split():
model.appendRow(QtGui.QStandardItem(text))
self.view.setModel(model)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.view)
def handleItemEntered(self, index):
if index.isValid():
QtGui.QToolTip.showText(
QtGui.QCursor.pos(),
index.data(),
self.view.viewport(),
self.view.visualRect(index)
)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 300, 200, 200)
window.show()
sys.exit(app.exec_())
Answered By - ekhumoro
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.