如何将信号对话框连接到插槽PyQt5

时间:2019-06-19 09:17:44

标签: python pyqt5

我正在研究PyQt5库,发现了一本书(使用Python和Qt进行快速GUI编程)。但是本书中的代码是用Python 2和PyQt4编写的。我正在使用Python 3和PyQt5。这段代码来自本书,我对其进行了更新以适合Python3。但是运行时仍然有问题。

import re
import PyQt5, sys

from PyQt5.QtCore import *

from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import ui_findandreplacedlg



MAC = "qt_mac_set_native_menubar" in dir()


class FindAndReplaceDlg(QDialog, ui_findandreplacedlg.Ui_FindAndReplaceDlg):
    def __init__(self,text,parent = None):
        super(FindAndReplaceDlg,self).__init__(parent)
        self.__text = str(text)
        self.__index = 0
        self.setupUi(self)
        if not MAC:
              self.findButton.setFocusPolicy(Qt.NoFocus)
              self.replaceButton.setFocusPolicy(Qt.NoFocus)
              self.replaceAllButton.setFocusPolicy(Qt.NoFocus)
              self.closeButton.setFocusPolicy(Qt.NoFocus)
        self.updateUi()

    @pyqtSlot("QString")
    def on_findLineEdit_textEdited(self, text):
        self.__index =0
        self.updateUi()

    def updateUi(self):

        enable = not self.findLineEdit.text().isEmpty()
        self.findButton.setEnabled(enable)
        self.replaceButton.setEnabled(enable)
        self.replaceAllButton.setEnabled(enable)

    def text(self):
        return self.__text

    @pyqtSlot()
    def on_findButton_clicked(self):
        regex = self.makeRegex()
        match = regex.search(self.__text,self.__index)
        if match is not None:
            self.__index = match.end()
            self.emit(SIGNSL("found"), match.start())
        else:
            self.emit(SIGNAL("not found"))

    def makeRegex(self):
        findText = str(self.on_findLineEdit.text())
        if str(self.syntaxComboBox.currentText()) == "Literal":
            findText = re.escape(findText)
        flags = re.MULTILINE|re.DOTALL|re.UNICODE
        if not self.caseCheckBox.isChecked():
            flags |=re.IGNORECASE
        if self.wholeCheckBox.isChecked():
            findText = r"\b%s\b" % findText 
        return re.compile(findText, flags)

    @pyqtSlot()
    def on_replaceButton_clicked(self):
        regex = self.makeRegex()
        self.__text = regex.sub(str(self.replaceLineEdit.text()), self.__text,1)

    @pyqtSlot()
    def on_replaceAllButton_clicked(self):
        regex = self.makeRegex()
        self.__text = regex.sub(str(self.replaceLineEdit.text()),self.__text)



if __name__ == "__main__":

    text = """US experience shows that, unlike traditional patents,
software patents do not encourage innovation and R&D, quite the contrary. In particular they hurt small and medium-sized
enterprises and generally  newcomers in the market. They will just weaken the market and increase spending on patents and
litigation, at the expense of technological innovation and research. Especially dangerous are attempts to abuse the patent system by preventing 
interoperability as a means of avoiding competition with technological ability. --- Extract quoted from Linus Torvalds and Alan Cox's letter
to the President of the European Parliament
http://www.effi.org/patentit/patents_torvalds_cox.html"""

    def found(where):
        print(("Found at %d" % where))

    def nomore():
        print ("No more found")

    app = QApplication(sys.argv)
    form = FindAndReplaceDlg(text)

    form.connect(form, SIGNAL("found"),nomore)

    form.connect(form, SIGNAL("not found"),found)

    form.show()
    app.exec_()
    print((form.text()))

此行的第一个错误

def updateUi(self):

    enable = not self.findLineEdit.text().isEmpty()
    ('str' object has no attribute 'isEmpty')

最后的第二个错误

 form = FindAndReplaceDlg(text)
 form.connect(form, SIGNAL("found"),nomore)
 form.connect(form, SIGNAL("not found"),found)

('FindAndReplaceDlg'没有属性'connect') 有人可以帮我吗?而且,如果您知道有什么新书可以研究Qt Desiner和PyQt5,我也会很高兴!

1 个答案:

答案 0 :(得分:1)

在PyQt4中,QLineEdit的文本方法返回一个QString,但在PyQt5中,它返回一个str以保持与python的兼容性,因此,如果要验证字符串是否为空,则必须使用python的传统方法。另一方面,在PyQt5中,您必须使用新的连接语法,此外,不再允许动态创建信号,因此必须将其更改为:

import re
from PyQt5 import QtCore, QtGui, QtWidgets
import ui_findandreplacedlg


MAC = "qt_mac_set_native_menubar" in dir()


class FindAndReplaceDlg(
    QtWidgets.QDialog, ui_findandreplacedlg.Ui_FindAndReplaceDlg
):
    found = QtCore.pyqtSignal(int)
    not_found = QtCore.pyqtSignal()

    def __init__(self, text, parent=None):
        super(FindAndReplaceDlg, self).__init__(parent)
        self.__text = str(text)
        self.__index = 0
        self.setupUi(self)
        if not MAC:
            for btn in (
                self.findButton,
                self.replaceButton,
                self.replaceAllButton,
                self.closeButton,
            ):
                btn.setFocusPolicy(QtCore.Qt.NoFocus)
        self.updateUi()

    @QtCore.pyqtSlot(str)
    def on_findLineEdit_textEdited(self, text):
        self.__index = 0
        self.updateUi()

    def updateUi(self):

        enable = bool(self.findLineEdit.text())
        self.findButton.setEnabled(enable)
        self.replaceButton.setEnabled(enable)
        self.replaceAllButton.setEnabled(enable)

    def text(self):
        return self.__text

    @QtCore.pyqtSlot()
    def on_findButton_clicked(self):
        regex = self.makeRegex()
        match = regex.search(self.__text, self.__index)
        if match is not None:
            self.__index = match.end()
            print(match.start())
            self.found.emit(match.start())
        else:
            self.not_found.emit()

    def makeRegex(self):
        findText = str(self.on_findLineEdit.text())
        if str(self.syntaxComboBox.currentText()) == "Literal":
            findText = re.escape(findText)
        flags = re.MULTILINE | re.DOTALL | re.UNICODE
        if not self.caseCheckBox.isChecked():
            flags |= re.IGNORECASE
        if self.wholeCheckBox.isChecked():
            findText = r"\b%s\b" % findText
        return re.compile(findText, flags)

    @QtCore.pyqtSlot()
    def on_replaceButton_clicked(self):
        regex = self.makeRegex()
        self.__text = regex.sub(
            str(self.replaceLineEdit.text()), self.__text, 1
        )

    @QtCore.pyqtSlot()
    def on_replaceAllButton_clicked(self):
        regex = self.makeRegex()
        self.__text = regex.sub(str(self.replaceLineEdit.text()), self.__text)


if __name__ == "__main__":
    import sys

    text = """US experience shows that, unlike traditional patents,
software patents do not encourage innovation and R&D, quite the contrary. In particular they hurt small and medium-sized
enterprises and generally  newcomers in the market. They will just weaken the market and increase spending on patents and
litigation, at the expense of technological innovation and research. Especially dangerous are attempts to abuse the patent system by preventing 
interoperability as a means of avoiding competition with technological ability. --- Extract quoted from Linus Torvalds and Alan Cox's letter
to the President of the European Parliament
http://www.effi.org/patentit/patents_torvalds_cox.html"""

    def found(where):
        print(("Found at %d" % where))

    def nomore():
        print("No more found")

    app = QtWidgets.QApplication(sys.argv)
    form = FindAndReplaceDlg(text)

    form.found.connect(nomore)

    form.not_found.connect(found)

    form.show()
    app.exec_()
    print((form.text()))