python - 如何在 PyQt5 中的外部事件过滤器方法中获取变量值?

标签 python pyqt pyqt5 eventfilter

嗨,我想打印在“eventFilter”方法中声明的变量的值?。在我的代码中,如果 focusitem 是 textbox1 那么 fitem = "textbox 1",如果焦点更改为 textbox 2 那么 fitem 是 "textbox2"等等。现在我想在方法之外打印 fitem。 (例如,在我的代码第 42 到 44 行中,尝试了一些操作,但什么也不会发生)

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

item1 = ["Python", "Python 2.7", "Python 2.9", "Python 3.5", "Python 3.7", "National", "Zebra",
        "Apple", "X Ray", "Boat", "Tiger", "Item001", "Item002", "Item003", "Item004", "Item005",
        "001Item", "002Item", "003Item", "004Item", "005Item", "Ball", "Cat", "Dog", "Fish",
        "Gold Fish", "Star Fish", "2821", "2822", "2823", "2811", "2812", "2813"]

item2 = ["India", "America", "Russia", "China", "England", "Iran", "Iraq", "Ice Land"]

item3 = ["Apple","Orange","Bannana","Grapes","Jack Fruit","Black","White","Green","Blue",
         "DarkBlue", "Light Blue","Red","Dark Red","Red Medium","Reddish Blue"]

fitem = None

class Check(QWidget):

    def __init__(self):
        super().__init__()
        self.setWindowTitle("Check Window")
        self.textbox1 = QLineEdit(self)
        self.textbox1.setGeometry(100, 100, 300, 30)
        self.textbox2 = QLineEdit(self)
        self.textbox2.setGeometry(100, 150, 300, 30)
        self.textbox3 = QLineEdit(self)
        self.textbox3.setGeometry(100, 200, 300, 30)

        self.lbox1 = QListWidget()
        self.lbox2 = QListWidget(self)
        self.lbox2.setGeometry(100, 250, 300, 500)
        self.textbox1.setObjectName("textbox1")
        self.textbox2.setObjectName("textbox2")
        self.textbox3.setObjectName("textbox3")

        self.textbox1.installEventFilter(self)
        self.textbox2.installEventFilter(self)
        self.textbox3.installEventFilter(self)
        self.lbox2.installEventFilter(self)

        # Based on focus item, I want to create some codes here.
        if fitem == "textbox1":
            print(" focus item is ", textbox1)


    def eventFilter(self, source, event):
        global fitem
        if event.type() == QEvent.FocusIn:
            if source == self.textbox1:
                self.lbox1.clear()
                self.lbox2.clear()
                self.lbox1.addItems(item1)
                self.lbox2.addItems(item1)
                fitem = "textbox1"
                print("textbox 1")

            elif source == self.textbox2:
                self.lbox1.clear()
                self.lbox2.clear()
                self.lbox1.addItems(item2)
                self.lbox2.addItems(item2)
                fitem = "textbox2"
                print("textbox 2")

            elif source == self.textbox3:
                self.lbox1.clear()
                self.lbox2.clear()
                self.lbox1.addItems(item3)
                self.lbox2.addItems(item3)
                fitem = "textbox3"
                print("textbox 3")

            elif source == self.lbox2:
                fitem = "listbox2"
                print("listbox 2")

        return super(Check, self).eventFilter(source, event)


def main():
    myapp = QApplication(sys.argv)
    mywin = Check()
    mywin.show()
    sys.exit(myapp.exec_())


if __name__ == "__main__":
    main()
    enter code here

最佳答案

在您的方法中,您有两个问题:

  • 你想要实现的逻辑只执行一次,因为它在构造函数中,而 eventFilter 在构造对象后执行。

  • 不要滥用变量,因为它们是不好的做法,请阅读 Why are global variables evil? .

逻辑是创建一个存储函数的属性,当您想要实现逻辑时调用的函数:


class Check(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Check Window")
        self.textbox1 = QLineEdit(self)
        self.textbox1.setGeometry(100, 100, 300, 30)
        self.textbox2 = QLineEdit(self)
        self.textbox2.setGeometry(100, 150, 300, 30)
        self.textbox3 = QLineEdit(self)
        self.textbox3.setGeometry(100, 200, 300, 30)

        self.lbox1 = QListWidget()
        self.lbox2 = QListWidget(self)
        self.lbox2.setGeometry(100, 250, 300, 500)
        self.textbox1.setObjectName("textbox1")
        self.textbox2.setObjectName("textbox2")
        self.textbox3.setObjectName("textbox3")

        self.textbox1.installEventFilter(self)
        self.textbox2.installEventFilter(self)
        self.textbox3.installEventFilter(self)
        self.lbox2.installEventFilter(self)

        <b>self.fitem = None</b>

    def eventFilter(self, source, event):
        if event.type() == QEvent.FocusIn:
            if source == self.textbox1:
                self.lbox1.clear()
                self.lbox2.clear()
                self.lbox1.addItems(item1)
                self.lbox2.addItems(item1)
                <b>self.fitem</b> = "textbox1"

            elif source == self.textbox2:
                self.lbox1.clear()
                self.lbox2.clear()
                self.lbox1.addItems(item2)
                self.lbox2.addItems(item2)
                <b>self.fitem</b> = "textbox2"

            elif source == self.textbox3:
                self.lbox1.clear()
                self.lbox2.clear()
                self.lbox1.addItems(item3)
                self.lbox2.addItems(item3)
                <b>self.fitem</b> = "textbox3"

            elif source == self.lbox2:
                <b>self.fitem</b> = "listbox2"
            <b>self.foo()</b>

        return super(Check, self).eventFilter(source, event)

    <b>def foo(self):
        if self.fitem == "textbox1":
            print("test")</b>

即使如此,我也不明白为什么你变得太复杂,在你的情况下使用 focusChanged 就足够了信号:

class Check(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Check Window")
        self.textbox1 = QLineEdit()
        self.textbox2 = QLineEdit()
        self.textbox3 = QLineEdit()
        self.lbox = QListWidget()

        lay = QVBoxLayout(self)
        lay.addWidget(self.textbox1)
        lay.addWidget(self.textbox2)
        lay.addWidget(self.textbox3)
        lay.addWidget(self.lbox)

        self.mapping_list = {
            self.textbox1: item1,
            self.textbox2: item2,
            self.textbox3: item3,
        }

        QApplication.instance().focusChanged.connect(self.on_focusChanged)

    def on_focusChanged(self, old, new):
        item = self.mapping_list.get(new)
        if item is not None:
            self.lbox.clear()
            self.lbox.addItems(item)
            print(" focus item is ", new)

关于python - 如何在 PyQt5 中的外部事件过滤器方法中获取变量值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62630154/

相关文章:

python - QProgressBar不显示复制进度

python - json.loads() 中的无效\转义,python 2.7

python - 在 QListFiew 中过滤/搜索 QFileSystemModel(可能是 QSortFilterProxyModel)

python - PyQt5 对不从 QObject 继承的类中的信号的支持

python - pyqt5 我想删除 QTreeWidget 中的箭头图标

python - 如何使用 python 隐藏 QTableView 中的复选框?

python - 重命名 Pandas 数据框中的选定列

python - 将 python 列表写成 CSV

python - 使用 PyQt4 的空白窗口

python - 在 PyQT 中获取布局的小部件