PySide:即时工具提示(在显示工具提示前不延迟)
问题描述:
我正在构建的工具使用工具提示在点击它之前显示有关文件的额外信息。如果有人能够借鉴一些如何实现这一点,这将是非常好的。我大约一个月到PySide,所以我无法破译我在网上找到的这些高级示例/答案,所以一个简单的代码示例和一些评论将帮助我解决很多问题。PySide:即时工具提示(在显示工具提示前不延迟)
这是我到目前为止。我不知道,当谈到事件我在做什么,所以这是我可以用代码示例做了最好的,我有:
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是描述如何创建即时提示后,但没有任何代码示例我不知道如何写这个。文档也不是很有帮助(它确实应该有初学者的简单例子)。
HERE是一个代码,显示如何实现鼠标移动事件,但我还没有能够得到它在我自己的例子上面工作。我不断收到错误,说:“TypeError:超级(类型,obj):obj必须是一个实例或类型的子类型”和“AttributeError:'Main_Window'对象没有属性'itemAt'”
再次,任何帮助或者想法会很棒。谢谢
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()
答
这是非常容易使用TreeView的entered信号做。如果您使用的参数showText的过载需要rect
参数,QToolTip
会自动完成其余的操作。
这里有一个简单的演示:
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_())
谢谢!这对于访问项目名称非常有用,但我希望能够访问存储在每个项目下的附加数据,当我将它添加到视图中时(在我的主代码中,我将创建该文件的用户存储为以及该文件的图像)。有关如何完成此任何想法?我在想,我必须用我为setToolTip()使用的参数替换handleItemEntered的index.data()。有一种更简单的方法吗?我已经添加了一个解决方案部分来显示我当前的代码,并在此评论中解释我正在讨论的内容。 –
@MikeBourbeau。您不应该再对该项目设置提示。它应该在'handleItemEntered'槽内构造并传递给'showText'。该项目可以通过'self.view.model()。itemFromIndex(index)'来检索。如果您需要向该项目添加额外数据,请使用带有自定义角色的[setData](http://doc.qt.io/qt-4.8/qstandarditem.html#setData)。 – ekhumoro