2015-07-12 120 views
1

我正在構建的工具使用工具提示在點擊它之前顯示有關文件的額外信息。如果有人能夠借鑑一些如何實現這一點,這將是非常好的。我大約一個月到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() 

回答

1

這是非常容易使用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_()) 
+0

謝謝!這對於訪問項目名稱非常有用,但我希望能夠訪問存儲在每個項目下的附加數據,當我將它添加到視圖中時(在我的主代碼中,我將創建該文件的用戶存儲爲以及該文件的圖像)。有關如何完成此任何想法?我在想,我必須用我爲setToolTip()使用的參數替換handleItemEntered的index.data()。有一種更簡單的方法嗎?我已經添加了一個解決方案部分來顯示我當前的代碼,並在此評論中解釋我正在討論的內容。 –

+1

@MikeBourbeau。您不應該再對該項目設置提示。它應該在'handleItemEntered'槽內構造並傳遞給'showText'。該項目可以通過'self.view.model()。itemFromIndex(index)'來檢索。如果您需要向該項目添加額外數據,請使用帶有自定義角色的[setData](http://doc.qt.io/qt-4.8/qstandarditem.html#setData)。 – ekhumoro