AttributeError: модуль 'PyQt5.QtCore' не имеет атрибута 'Slot' - PullRequest
0 голосов
/ 22 мая 2018

Я все еще новичок в Python, и я не уверен, как правильно подключить сигналы в PyQt5.Мой код ниже сделан на PyQt4, и я хотел бы преобразовать его в более новый стандарт.(В основном я написал это в другой среде, и теперь я пытаюсь заставить его работать на этом компьютере)

Как правильно подключить элементы графического интерфейса к каждой функции?Прежде чем я подключил свой элемент кнопки 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_()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...