2015-07-12 1 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: super (type, obj): obj должен быть экземпляром или подтипом типа» и «AttributeError: объект« Main_Window »не имеет атрибута« itemAt »»

Опять же, любая помощь или мысли были бы замечательными. Спасибо

РЕШЕНИЕ

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

Это гораздо проще сделать с помощью entered сигнала в TreeView в. И если вы используете перегрузку 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

Спасибо! Это отлично подходит для доступа к имени элемента, но я хотел бы иметь доступ к дополнительным данным, которые я храню под каждым элементом, когда добавляю его в представление (в моем основном коде я храню пользователя, который создал файл как а также образ файла). Любые мысли о том, как это сделать? Я думаю, что мне нужно заменить index.data() аргументом handleItemEntered аргументом, который я использую для setToolTip(). Есть ли более простой способ? Я добавил раздел решения, чтобы показать свой текущий код и объяснить, о чем я говорю в этом комментарии. –

+1

@MikeBourbeau. Вам больше не нужно устанавливать всплывающую подсказку. Он должен быть построен в слоте 'handleItemEntered' и передан' showText'. Элемент может быть восстановлен с помощью 'self.view.model(). ItemFromIndex (index)'. Если вам нужно добавить дополнительные данные к элементу, используйте [setData] (http://doc.qt.io/qt-4.8/qstandarditem.html#setData) с настраиваемой ролью. – ekhumoro

Смежные вопросы