pyside信号和槽

python3确实不错,连.py挡都不用加 #coding注释了。

自定义了一个信号,结果报错:

AttributeError: 'FindAndReplaceDlg' object has no attribute 'not_fount'

原来,又给忘了,使用Signal定义信号,要把它放在__init__外面,放在构造器里,就会报错。

在构造器外面定义的变量,给叫做类属性,所有的实例都共享相同的值。

但是Signal却不是。

A signal (specifically an unbound signal) is an attribute of a class that is a sub-class of QObject. When a signal is referenced as an attribute of an instance of the class then PyQt4 automatically binds the instance to the signal in order to create a bound signal. This is the same mechanism that Python itself uses to create bound methods from class functions.

信号(特别是未绑定信号)是类的属性,类是QObject的子类。当以类实例的属性身份引用一个信号时,PyQt4就自动地把实例和此信号绑在一起,从而生成一个绑定信号。

Python本身从类函数生成绑定函数也是同样的机制。


因此,此Signal不会被多个实例分享。

pyside信号和槽_第1张图片


import re
import sys
import ui_fr
from PySide.QtCore import *
from PySide.QtGui import *


class FindAndReplaceDlg(QDialog, ui_fr.Ui_Dialog):
    #使用Signal宏定义两个信号
    #必须在__init__之前
    found = Signal(str)
    not_found = Signal()

    #class attribute
    index = 0

    def __init__(self, text, parent=None):
        super(FindAndReplaceDlg, self).__init__(parent)
        self.setupUi(self)
        self.__text = text
        found = Signal(str)
        not_found = Signal()

    #编辑框findEdit文本编辑 槽
    @Slot()
    def on_findEdit_textEdited(self):
        self.text = self.findEdit.text()

    #查找按钮 槽
    @Slot()
    def on_btnFind_clicked(self):
        pattern = self.makeRegex()
        match = pattern.search(self.__text)
        if match:
            #print(match.group())
            self.found.emit(match.group())

            #测试类变量
            FindAndReplaceDlg.index += 10
            print(self.index)
        else:
            self.not_found.emit()

    #替换按钮 槽
    @Slot()
    def on_btnReplace_clicked(self):
        pattern = self.makeRegex()
        self.__text = pattern.sub(self.replaceEdit.text(), self.__text, 1)
        print(self.__text)

    #替换所有的按钮 槽
    @Slot()
    def on_btnReplaceAll_clicked(self):
        pattern = self.makeRegex()
        self.__text = pattern.sub(self.replaceEdit.text(), self.__text)
        print(self.__text)

    def makeRegex(self):
        #re表达式
        find_text = self.findEdit.text()
        #print('大家好', self.comboBox.currentText())
        if self.comboBox.currentText() == 'Literal text':
            find_text = re.escape(find_text)

        flag = re.MULTILINE | re.DOTALL | re.UNICODE
        if not self.caseCheck.isChecked():
            flag |= re.IGNORECASE
        if self.wholeCheck.isChecked():
            find_text = r'\b%s\b' % find_text
        return re.compile(find_text, flag)


if __name__ == '__main__':

    #不使用Slot修饰符
    def find(str):
        print('find %s' % str)

    def not_find():
        print('not find')

    def find_2(str):
        print('i am g, find %s' % str)

    app = QApplication(sys.argv)
    text = """
    a brown fox jump quicly from the lazy dog, and wind is biger and beiger
There are signs of unease about the tone of these laws
...
Quoted from Henry Porter, The Observer, December 31, 2006.
    """
    f = FindAndReplaceDlg(text)

    #f.connect(f, SIGNAL('find'), find)
    #f.connect(f, SIGNAL('notfind'),not_find)
    #连接信号和槽
    f.found.connect(find)
    f.not_found.connect(not_find)

    #显示对话框
    f.show()

    #信号是否分享?
    text_1 = 'Good moring, every boy and girls!'
    g = FindAndReplaceDlg(text_1)
    g.found.connect(find_2)
    g.show()

    app.exec_()


这里,还创建了一个类属性,index,但是结果对它修改无效。

而且可以实验到,实例f和实例g之间不会发生信号共享的情况。


而使用其他方式定义类,则类属性(经常被叫做类变量),可以修改:

class Dog:


    tricks = []             # mistaken use of a class variable


    def __init__(self, name):
        self.name = name


    def add_trick(self, trick):
        self.tricks.append(trick)


d = Dog('Fido')
e = Dog('Buddy')
d.add_trick('roll over')
e.add_trick('play dead')
print(d.tricks)                # unexpectedly shared by all dogs


pyside信号和槽_第2张图片


Generally speaking, instance variables are for data unique to each instance and class variables are for attributes and methods shared by all instances of the class.

一般来讲,对于每个实例,实例变量是独一的;而类变量主要用于类实例共享的属性和方法。

上例子中,应该把tricks放到__init__中定义才合适。


你可能感兴趣的:(Python)