2012-02-23 7 views
6

QListViewを使用して、カスタムペイントでカスタムデリゲートを使用してアイテムを表示します。各項目(すなわち各リスト行)内で、ユーザがクリックしていくつかの機能を呼び出すことのできる2つの「ハイパーリンク」を表示できるようにしたいと考えています。カスタムペイントデリゲート内のクリック可能な要素または子ウィジェット

私は公式のドキュメント(例:Model/View Programming)とグーグルグーグルをチェックしようとしましたが、これを達成する方法を見つけることができませんでした。

  • が、私はフラットのQPushButtonのように、子ウィジェットを使用してそれらを描くことができます:

    は、私は2つのアイデアを、自分の問題と、それぞれを持っています。どのようにこれらのウィジェットを配置して表示するのですか?

  • テキスト文字列として描画することもできます。どのようにしてそれらをクリック可能にするのですか?または、親QListViewでクリックイベントをキャプチャして、何らかの方法で座標を決定できますか?次に、これらのクリック可能な要素に座標を一致させ、それに応じて動作させることができます。

私の初期のアプローチは、レイアウトと子ウィジェットを持つ適切なウィジェットを持っていた.setItemWidget()でQListWidgetを使用することでした。残念ながら、私のリストが数百または数千のアイテムに成長したとき、これは遅すぎました。だから私は代理人を使ってQListViewに変更しました。

答えて

1

私は解決策に近づいているようです。

デリゲートの.editorEvent(event, model, option, index)をオーバーライドすることで、要素のクリックを受け取ることができます。 event.type()、クリックされた行がindex.row()、実際の座標がevent.x()event.y()であることがわかります(イベントタイプがMouseButtonReleaseの場合、イベントはQMouseEventです)。

これから、私は画面上の要素に座標を関連付けることができ、それに応じて行動できると思います。

作業コードを取得すると、この回答が更新されます。

EDIT

単純な実施例、使用PySide:

class MyModel(QtGui.QStandardItemModel): 
    def __init__(self): 
    super(MyModel, self).__init__() 
    for i in range(10): self.appendRow(QtGui.QStandardItem("Row %d" % i)) 

class MyDelegate(QtGui.QStyledItemDelegate): 
    def __init__(self, parent=None): 
    super(MyDelegate, self).__init__(parent) 
    self.links = {} 

    def makeLinkFunc(self, row, text): 
    def linkFunc(): print("Clicked on %s in row %d" % (text, row)) 
    return linkFunc 

    def paint(self, painter, option, index): 
    painter.save() 
    textHeight = QtGui.QFontMetrics(painter.font()).height() 

    painter.drawText(option.rect.x()+2, option.rect.y()+2+textHeight, index.data()) 

    rowLinks = {} 
    for i in range(3): 
     text = "Link %d" % (3-i) 
     linkWidth = QtGui.QFontMetrics(font).width(text) 
     x = option.rect.right() - (i+1) * (linkWidth + 10) 
     painter.drawText(x, y, text) 
     rect = QtCore.QRect(x, y - textHeight, linkWidth, textHeight) 
     rowLinks[rect] = self.makeLinkFunc(index.row(), text) 

    self.links[index.row()] = rowLinks 
    painter.restore() 

    def sizeHint(self, option, index): 
    hint = super().sizeHint(option, index) 
    hint.setHeight(30) 
    return hint 

    def editorEvent(self, event, model, option, index): 
    if event.type() == QtCore.QEvent.MouseButtonRelease: 
     for rect, link in self.links[index.row()].items(): 
     if rect.contains(event.pos()): 
      link() 
      return True 
    return False 

listmodel = MyModel() 
listview = QtGui.QListView() 
listview.setModel(listmodel) 
listview.setItemDelegate(MyDelegate(parent=listview)) 
listview.setSelectionMode(QtGui.QAbstractItemView.NoSelection) 
関連する問題