代码之家  ›  专栏  ›  技术社区  ›  Potion

AttributeError:模块“PyQt5”。QtCore没有属性Slot

  •  0
  • Potion  · 技术社区  · 8 年前

    我还是python新手,不知道如何在PyQt5中正确连接信号。我下面的代码是用PyQt4编写的,我想把它转换成新的标准。(基本上我是在一个不同的环境中起草的,现在我正试图让它在这台机器上工作)

    如何将gui元素正确连接到每个函数?在我连接按钮元件之前 pushButtonNext 通过:

    @QtCore.Slot()
    def on_pushButtonSolution_clicked(self):
        print('Total Solutions to Display {}'.format(self.total_questions))
    

    为了连接菜单项,我在 __init__ :

    self.actionNew.triggered.connect(self.MenuNew)
    self.actionNew.setShortcut("Ctrl+N")
    

    哪里 MenuNew() 详情如下:

    def MenuNew(self):
    print('clicked on new')
    fileToOpen = QtWidgets.QFileDialog.getOpenFileName(self)
    print(fileToOpen)
    if(fileToOpen[0] is not ''):
        print('Change doc')
        self.clearObjects()
        self.setWindowTitle("OpenTester - " + fileToOpen[0])
        #self.convertDocx(fileToOpen[0])
        #self.parse(fileToOpen[0])
        self.displayQuestion(self.test[0],1)
    

    为了方便起见,以下是我的完整代码:

    # -*- coding: utf-8 -*-
    # imports for gui
    import sys
    import os
    from PyQt5 import QtCore, QtWidgets, uic, QtGui
    
    #from testevalutils import gui
    # imports for parser
    import docx2txt
    
    import Question
    
    
    # Path to the directory containing this .py file (same directory as .ui file)
    THIS_DIR = os.path.abspath(os.path.dirname(__file__))
    
    
    class MainWindow(QtWidgets.QMainWindow):
        def __init__(self, parent=None):
            # Calls the QDialog __init__ method with the given parent
            super().__init__(parent)
    
            # Load the ui file (created by Qt Designer)
            ui_path = os.path.abspath(os.path.join(THIS_DIR, 'MainWindow.ui'))
            uic.loadUi(ui_path, self)
    
            # initialize test variables
            self.test = []
            self.total_questions = 0
            self.currentQuestion = 0
            self.displayedQuestion = None
    
            # elements
            self.checkBoxFlag.setText("QUESTION NUM / 999")
            self.textBrowserQuestion.setText("")
    
            # menu bar
            self.actionNew.triggered.connect(self.MenuNew)
            self.actionNew.setShortcut("Ctrl+N")
    
        # This decorator (@QtCore.Slot) makes it so this method is automatically
        # connected to the "clicked" signal of the "pushButton_Add" widget by
        # using the naming convention "on_<ObjectName>_<SignalName>"
        @QtCore.Slot()
        def on_actionNew_clicked(self):
            print('Menu>New clicked')
    
        @QtCore.Slot()
        def on_pushButtonSolution_clicked(self):
            print('Total Solutions to Display {}'.format(self.total_questions))
    
        @QtCore.Slot()
        def on_pushButtonNext_clicked(self):
            print('Next pushed')
            self.saveState()
    
            # if not at the last question
            if (self.currentQuestion is self.total_questions):
                print("Finished!")
            else:
                self.currentQuestion = self.currentQuestion + 1
                self.displayQuestion(self.test[self.currentQuestion],1)
    
        @QtCore.Slot()
        def on_pushButtonBack_clicked(self):
            print('Back pushed')
            self.saveState()
            # go to next question in test array
            self.currentQuestion = self.currentQuestion - 1
            self.displayQuestion(self.test[self.currentQuestion],1)
    
        # Saves any user changes with check box selections
        # usually called when next or back button is pushed
        def saveState(self):
            checkBoxState = self.checkBoxFlag.isChecked()
            answers = []
            answer1State = self.checkBoxAnswer1.isChecked()
            answers.append(answer1State)
            answer2State = self.checkBoxAnswer2.isChecked()
            answers.append(answer2State)
            answer3State = self.checkBoxAnswer3.isChecked()
            answers.append(answer3State)
            answer4State = self.checkBoxAnswer4.isChecked()
            answers.append(answer4State)
            self.displayedQuestion.SaveState(checkBoxState, answers)
            print('The answer is set to {} {} {} {}'.format(answer1State,answer2State,answer3State,answer4State))
    
        def disableButton(self, button):
            button.setEnabled(False)
    
        ### Helper methods ###
        def displayQuestion(self, Question, Number):
            # display question from object we've parsed
            # Add one due to index 0
            num = self.currentQuestion + 1
            self.checkBoxFlag.setText("Question {} of {}".format(num, len(self.test)))
            self.textBrowserQuestion.setText(Question.question)
            self.checkBoxAnswer1.setText(Question.AnswerSetAt(0))
            self.checkBoxAnswer2.setText(Question.AnswerSetAt(1))
            self.checkBoxAnswer3.setText(Question.AnswerSetAt(2))
            self.checkBoxAnswer4.setText(Question.AnswerSetAt(3))
    
            # load user changes
            self.checkBoxFlag.setChecked(Question.IsFlagged())
            self.checkBoxAnswer1.setChecked(Question.LoadAnswer(0))
            self.checkBoxAnswer2.setChecked(Question.LoadAnswer(1))
            self.checkBoxAnswer3.setChecked(Question.LoadAnswer(2))
            self.checkBoxAnswer4.setChecked(Question.LoadAnswer(3))
    
            #if first question disable next button
            if(num is 1):
                self.pushButtonBack.setEnabled(False)
            elif (num is self.total_questions - 1):
                self.pushButtonNext.setText("Finish")
            else:
                self.pushButtonBack.setEnabled(True)
                self.pushButtonNext.setText("Next")
            self.displayedQuestion = self.test[self.currentQuestion]
            None
    
        # Create a txt file "_processed" to read from
        def convertDocx(self, filename):
            rawtext = docx2txt.process(filename + '.docx')
            f = open(filename + '_processed.txt', 'w')
            f.write(rawtext)
            f.close()
    
        def incrementQuestion(self):
            self.total_questions = self.total_questions + 1
    
        def addToTest(self, Question):
            self.test.append(Question)
    
        def clearObjects(self):
            self.test = []
            self.total_questions = 0
            self.currentQuestion = 0
            self.displayedQuestion = 1
    
        def MenuNew(self):
            print('clicked on new')
            fileToOpen = QtWidgets.QFileDialog.getOpenFileName(self)
            print(fileToOpen)
            if(fileToOpen[0] is not ''):
                print('Change doc')
                self.clearObjects()
                self.setWindowTitle("OpenTester - " + fileToOpen[0])
                #self.convertDocx(fileToOpen[0])
                #self.parse(fileToOpen[0])
                self.displayQuestion(self.test[0],1)
    
        # Parse from the txt file
        def parse(self, filename):
            question_block = False
            answer_block = False
            explain_block = False
            with open(filename + '_processed.txt') as openfileobject:
                # set our variable for the question
                q_number = None
                q_question = ""
                q_options = []
                q_answer = None
                q_explain = ""
                for line in openfileobject:
                    # line.split('\n')
                    # print(line)
                    # if only a new line then skip it
                    if(line == "\n"):
                        continue
                    if (not question_block and "QUESTION" in line):
                        question_block = True
                        q_number = line
                        self.total_questions = self.total_questions + 1
                        # skip to next line to check for its properties
                        continue
                    # if found next qustion then get each propertiy and add them
                    if(question_block):
                        #keep adding lines until we reach the end
                        if("?") in line:
                            question_block = False
                            answer_block = True
                        q_question = q_question + line
                        continue
                    if(answer_block):
                        if("A. " in line or "B. " in line or "C. " in line or "D. " in line):
                            line = line[:-1]
                            q_options.append(line)
                            continue
                        if("Correct Answer:") in line:
                            q_answer = line
                            answer_block = False
                            explain_block = True
                            continue
                    if(explain_block):
                        if("Reference" not in line):
                            q_explain = q_explain + line
                            continue
                        else:
                            explain_block = False
                            # Add everything into one question
                            new_question = Question.Question(q_number, q_question, q_options, q_answer, q_explain)
                            self.addToTest(new_question)
                            # Reset our question
                            q_number = None
                            q_question = ""
                            q_options = []
                            q_answer = None
                            q_explain = ""
    
    
    if __name__ == '__main__':
        """Main function that tests the dialog."""
        app = QtWidgets.QApplication.instance()
        if not app:
            app = QtWidgets.QApplication([])
        # This ensures errors are reported from GUI callbacks.
        # Otherwise it would
    #    gui.handle_unhandled()
    
        filedocx = 'comptia_practice_3-21-2018'
    
        # initialize our window along with the test components already
        w = MainWindow()
        w.show()
        w.setWindowTitle("OpenTester - " + filedocx + ".docx")
    
    
        w.convertDocx(filedocx)
        w.parse(filedocx)
        # load first question object
        w.displayQuestion(w.test[w.currentQuestion],1)
    
        # execute app
        app.exec_()
    
    0 回复  |  直到 8 年前