PyQt - Как обработать исключения импорта модуля - PullRequest
2 голосов
/ 04 января 2012

Я нигде не могу найти решение, как обрабатывать исключения при импорте модулей. Мне нужно импортировать модуль 'enchant', но я должен проверить, установлен ли он первым. И мне нужно показать сообщение об ошибке, если оно не установлено. Поэтому, если я сделаю это, я не смогу показать QMessageBox, потому что основной класс еще не создан.

import sys
import re

from PyQt4.QtCore import *
from PyQt4.QtGui import *

try:
    import enchant
    dict_list = enchant.list_languages()
    if "ru_RU" in dict_list:
        self.dict = enchant.Dict("ru_RU")
    else:
        self.dict = enchant.Dict()
except ImportError, inst:
    #How do I graphically show an error message here if the class hasn't been set up yet?

class Translit(QMainWindow):
    def __init__(self, parent = None):
        super(Translit, self).__init__(parent)

Если я сделаю это:

import sys
import re

from PyQt4.QtCore import *
from PyQt4.QtGui import *

class Translit(QMainWindow):
    def __init__(self, parent = None):
        super(Translit, self).__init__(parent)

    try:
        import enchant
        dict_list = enchant.list_languages()
        if "ru_RU" in dict_list:
            self.dict = enchant.Dict("ru_RU")
        else:
            self.dict = enchant.Dict()
    except ImportError, inst:
        QMessageBox.warning(parent, "", "Error:\n%s seems to be installed\n\nSpell checking will be disabled" % (inst))

    self.change_dict()

    def change_dict(self):
        self.dict = enchant.Dict("en_US")
        QMessageBox.about(parent,"","Spellcheck is set to " + self.dict.tag)

тогда интерпретатор жалуется: «NameError: глобальное имя enchant не определено».

Пожалуйста, покажите мне, как я могу показать сообщения об исключении импорта модуля или как заставить этот модуль работать во всей программе. Спасибо.

Вот исходный код, который я пытаюсь использовать повторно:

__license__ = 'MIT'
__copyright__ = '2009, John Schember '
__docformat__ = 'restructuredtext en'

import re
import sys

import enchant

from PyQt4.Qt import QAction
from PyQt4.Qt import QApplication
from PyQt4.Qt import QEvent
from PyQt4.Qt import QMenu
from PyQt4.Qt import QMouseEvent
from PyQt4.Qt import QPlainTextEdit
from PyQt4.Qt import QSyntaxHighlighter
from PyQt4.Qt import QTextCharFormat
from PyQt4.Qt import QTextCursor
from PyQt4.Qt import Qt
from PyQt4.QtCore import pyqtSignal


class SpellTextEdit(QPlainTextEdit):

def __init__(self, *args):
    QPlainTextEdit.__init__(self, *args)

    # Default dictionary based on the current locale.
    self.dict = enchant.Dict("ru_RU")
    self.highlighter = Highlighter(self.document())
    self.highlighter.setDict(self.dict)

def mousePressEvent(self, event):
    if event.button() == Qt.RightButton:
        # Rewrite the mouse event to a left button event so the cursor is
        # moved to the location of the pointer.
        event = QMouseEvent(QEvent.MouseButtonPress, event.pos(),
            Qt.LeftButton, Qt.LeftButton, Qt.NoModifier)
    QPlainTextEdit.mousePressEvent(self, event)

def contextMenuEvent(self, event):
    popup_menu = self.createStandardContextMenu()

    # Select the word under the cursor.
    cursor = self.textCursor()
    cursor.select(QTextCursor.WordUnderCursor)
    self.setTextCursor(cursor)

    # Check if the selected word is misspelled and offer spelling
    # suggestions if it is.
    if self.textCursor().hasSelection():
        text = unicode(self.textCursor().selectedText())
        if not self.dict.check(text):
            spell_menu = QMenu('Spelling Suggestions')
            for word in self.dict.suggest(text):
                action = SpellAction(word, spell_menu)
                action.correct.connect(self.correctWord)
                spell_menu.addAction(action)
            # Only add the spelling suggests to the menu if there are
            # suggestions.
            if len(spell_menu.actions()) != 0:
                popup_menu.insertSeparator(popup_menu.actions()[0])
                popup_menu.insertMenu(popup_menu.actions()[0], spell_menu)

    popup_menu.exec_(event.globalPos())

def correctWord(self, word):
    '''
    Replaces the selected text with word.
    '''
    cursor = self.textCursor()
    cursor.beginEditBlock()

    cursor.removeSelectedText()
    cursor.insertText(word)

    cursor.endEditBlock()

class Highlighter(QSyntaxHighlighter):

WORDS = u'(?iu)[\w\']+'

def __init__(self, *args):
    QSyntaxHighlighter.__init__(self, *args)

    self.dict = None

def setDict(self, dict):
    self.dict = dict

def highlightBlock(self, text):
    if not self.dict:
        return

    text = unicode(text)

    format = QTextCharFormat()
    format.setUnderlineColor(Qt.red)
    format.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline)

    for word_object in re.finditer(self.WORDS, text):
        if not self.dict.check(word_object.group()):
            self.setFormat(word_object.start(),
                word_object.end() - word_object.start(), format)

class SpellAction(QAction):

'''
A special QAction that returns the text in a signal.
'''

correct = pyqtSignal(unicode)

def __init__(self, *args):
    QAction.__init__(self, *args)

    self.triggered.connect(lambda x: self.correct.emit(
        unicode(self.text())))

def main(args=sys.argv):
app = QApplication(args)

spellEdit = SpellTextEdit()
spellEdit.show()

return app.exec_()

if __name__ == '__main__':
    sys.exit(main()) 

1 Ответ

1 голос
/ 04 января 2012

Вот одно из возможных решений вашей проблемы:

from PyQt4.QtCore import *
from PyQt4.QtGui import *

try:
    import enchant
except ImportError:
    enchant = None

class Translit(QMainWindow):
    def __init__(self, parent = None):
        super(Translit, self).__init__(parent)
        if enchant is not None:
            dict_list = enchant.list_languages()
            if "ru_RU" in dict_list:
                self.dict = enchant.Dict("ru_RU")
            else:
                self.dict = enchant.Dict()
            self.change_dict()
        else:
            self.dict = None
            QMessageBox.warning(parent, "",
                "Error: could not import the 'enchant' module\n\n"
                "Spell checking will be disabled")

    def change_dict(self):
        if self.dict is not None:
            self.dict = enchant.Dict("en_US")
            QMessageBox.about(
                parent, "", "Spellcheck is set to " + self.dict.tag)

Однако, если проверка орфографии является необязательной функцией, я как пользователь был бы весьма раздражен, если бы получал это предупреждение каждый раз, когда запускал приложение.

Было бы лучше показать предупреждение, когда пользователь впервые попытается получить доступ к проверке орфографии (а затем отключит дальнейший доступ). Но способ сделать это, очевидно, будет зависеть от того, как модуль enchant используется в других местах вашего приложения.

...