【问题标题】:Find first occurrence of a text inside a QTreeView-column在 QTreeView 列中查找第一次出现的文本
【发布时间】:2019-10-20 10:22:46
【问题描述】:

在我的主窗口中,我有一个 QTreeView 类的表。第二列包含邮件的主题。单击一个按钮,我想搜索一个特定的字符,比如说“Y”。现在我希望表格跳转到第一个找到的以字母“Y”开头的主题。

请参阅以下示例。

当您选择第二列(“主题”)中的任何单元格并开始输入“y”时,这将起作用 -> 表格会突出显示第一次出现的地方。 -> 请参阅下划线项目“您的电话账单”。当它看不见时,它甚至会滚动到那个单元格。

我正是想要这个 - 但在一个按钮上实现,请参阅“搜索主题 'Y'”,信号“on_pbSearch_Y_clicked()”。

完整的功能代码(到目前为止):

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class App(QWidget):
    MAIL_RANGE = 4
    ID, FROM, SUBJECT, DATE = range(MAIL_RANGE)

    def __init__(self):
        super().__init__()      
        self.left = 10
        self.top = 10
        self.width = 640
        self.height = 240
        self.initUI()

        self.dataView.setSelectionMode(QAbstractItemView.ExtendedSelection)  #  <- enable selection of rows in tree
        self.dataView.setEditTriggers(QAbstractItemView.NoEditTriggers)      #  <- disable editing items in tree

        for i in range(0, 2):
            self.dataView.resizeColumnToContents(i)        

        self.pbSearch_Y = QPushButton(self)
        self.pbSearch_Y.setText("Search Subj 'Y'")
        self.pbSearch_Y.move(500,0)        

        self.pbSearch_Y.show()

        # connect handlers        
        self.pbSearch_Y.clicked.connect(self.on_pbSearch_Y_clicked)

    def on_pbSearch_Y_clicked(self):
        pass

    def initUI(self):        
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.dataGroupBox = QGroupBox("Inbox")
        self.dataView = QTreeView()
        self.dataView.setRootIsDecorated(False)
        self.dataView.setAlternatingRowColors(True)        

        dataLayout = QHBoxLayout()
        dataLayout.addWidget(self.dataView)
        self.dataGroupBox.setLayout(dataLayout)

        model = self.createMailModel(self)
        self.dataView.setModel(model)
        self.addMail(model, 1, 'service@github.com', 'Your Github Donation','03/25/2017 02:05 PM')
        self.addMail(model, 2, 'support@github.com', 'Github Projects','02/02/2017 03:05 PM')
        self.addMail(model, 3, 'service@phone.com', 'Your Phone Bill','01/01/2017 04:05 PM')
        self.addMail(model, 4, 'service@abc.com', 'aaaYour Github Donation','03/25/2017 02:05 PM')
        self.addMail(model, 5, 'support@def.com', 'bbbGithub Projects','02/02/2017 03:05 PM')
        self.addMail(model, 6, 'service@xyz.com', 'cccYour Phone Bill','01/01/2017 04:05 PM')

        self.dataView.setColumnHidden(0, True)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.dataGroupBox)
        self.setLayout(mainLayout)

        self.show()

    def createMailModel(self,parent):
        model = QStandardItemModel(0, self.MAIL_RANGE, parent)
        model.setHeaderData(self.ID, Qt.Horizontal, "ID")
        model.setHeaderData(self.FROM, Qt.Horizontal, "From")
        model.setHeaderData(self.SUBJECT, Qt.Horizontal, "Subject")
        model.setHeaderData(self.DATE, Qt.Horizontal, "Date")
        return model

    def addMail(self, model, mailID, mailFrom, subject, date):
        model.insertRow(0)
        model.setData(model.index(0, self.ID), mailID)
        model.setData(model.index(0, self.FROM), mailFrom)
        model.setData(model.index(0, self.SUBJECT), subject)
        model.setData(model.index(0, self.DATE), date)        

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

我怎样才能做到这一点?

【问题讨论】:

    标签: python python-3.x pyqt pyqt5 qtreeview


    【解决方案1】:

    您必须执行以下操作:

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    import sys
    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    class App(QtWidgets.QWidget):
        MAIL_RANGE = 4
        ID, FROM, SUBJECT, DATE = range(MAIL_RANGE)
    
        def __init__(self):
            super().__init__()
            self.initUI()
    
        def initUI(self):
            self.setGeometry(10, 10, 640, 240)
    
            self.dataGroupBox = QtWidgets.QGroupBox("Inbox")
            self.dataView = QtWidgets.QTreeView(
                rootIsDecorated=False,
                alternatingRowColors=True,
                selectionMode=QtWidgets.QAbstractItemView.ExtendedSelection,
                editTriggers=QtWidgets.QAbstractItemView.NoEditTriggers,
                selectionBehavior=QtWidgets.QAbstractItemView.SelectRows,
            )
    
            dataLayout = QtWidgets.QHBoxLayout()
            dataLayout.addWidget(self.dataView)
            self.dataGroupBox.setLayout(dataLayout)
    
            model = App.createMailModel(self)
            self.dataView.setModel(model)
    
            for i in range(0, 2):
                self.dataView.resizeColumnToContents(i)
    
            self.addMail(model, 1, 'service@github.com', 'Your Github Donation','03/25/2017 02:05 PM')
            self.addMail(model, 2, 'support@github.com', 'Github Projects','02/02/2017 03:05 PM')
            self.addMail(model, 3, 'service@phone.com', 'Your Phone Bill','01/01/2017 04:05 PM')
            self.addMail(model, 4, 'service@abc.com', 'aaaYour Github Donation','03/25/2017 02:05 PM')
            self.addMail(model, 5, 'support@def.com', 'bbbGithub Projects','02/02/2017 03:05 PM')
            self.addMail(model, 6, 'service@xyz.com', 'cccYour Phone Bill','01/01/2017 04:05 PM')
    
            self.dataView.setColumnHidden(0, True)
    
            self.leSearch = QtWidgets.QLineEdit()
            self.pbSearch = QtWidgets.QPushButton(
                "Search", clicked=self.on_pbSearch_clicked
            )
    
            hlay = QtWidgets.QHBoxLayout()
            hlay.addWidget(self.leSearch)
            hlay.addWidget(self.pbSearch)
    
            mainLayout = QtWidgets.QVBoxLayout(self)
            mainLayout.addLayout(hlay)
            mainLayout.addWidget(self.dataGroupBox)
    
        @staticmethod
        def createMailModel(parent):
            model = QtGui.QStandardItemModel(0, App.MAIL_RANGE, parent)
            for c, text in zip(
                (App.ID, App.FROM, App.SUBJECT, App.DATE),
                ("ID", "From", "Subject", "Date"),
            ):
                model.setHeaderData(c, QtCore.Qt.Horizontal, text)
            return model
    
        def addMail(self, model, mailID, mailFrom, subject, date):
            model.insertRow(0)
            for c, text in zip(
                (App.ID, App.FROM, App.SUBJECT, App.DATE),
                (mailID, mailFrom, subject, date),
            ):
                model.setData(model.index(0, c), text)
    
        @QtCore.pyqtSlot()
        def on_pbSearch_clicked(self):
            text = self.leSearch.text()
            self.leSearch.clear()
            if text:
                # find index
                start = self.dataView.model().index(0, 2)
                ixs = self.dataView.model().match(
                    start,
                    QtCore.Qt.DisplayRole,
                    text,
                    hits=1,
                    flags=QtCore.Qt.MatchStartsWith,
                )
                if ixs:
                    ix = ixs[0]
    
                    # scroll to index
                    self.dataView.scrollTo(ix)
    
                    # select row
                    ix_from = ix.sibling(ix.row(), 0)
                    ix_to = ix.sibling(
                        ix.row(), self.dataView.model().columnCount() - 1
                    )
                    self.dataView.selectionModel().select(
                        QtCore.QItemSelection(ix_from, ix_to),
                        QtCore.QItemSelectionModel.SelectCurrent,
                    )
            else:
                self.dataView.clearSelection()
    
    
    if __name__ == "__main__":
        app = QtWidgets.QApplication(sys.argv)
        ex = App()
        ex.show()
        sys.exit(app.exec_())
    

    【讨论】:

      【解决方案2】:

      老实说,我不会在 python 中使用 GUI,但是您可以通过 PyQT 将我的任意函数替换为所需的函数来实现

      mostWantedChar = 'Y'
      foundElements = []
      for element in dataView.listElements():
          if element[0] == mostWantedChar:
              foundElements.Append(element + '@' + element.Line()) #In case you would need to get the line and the line's content for further purposes (just make a split('@') )
              element.Line().Higlight()
          waitClickFromPushButton()
      return foundElements
      

      【讨论】:

        猜你喜欢
        • 2021-08-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多