PyQt - 如何处理模块导入异常

2 投票
1 回答
1433 浏览
提问于 2025-04-17 09:30

我到处找都找不到解决办法,怎么处理模块导入时的错误。我需要导入'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: global name 'enchant' is not defined”。

请告诉我怎么才能显示模块导入错误的信息,或者怎么让这个模块在整个程序中都能用。谢谢。

这是我想要重用的原始代码:

__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

这里有一个可能的解决办法:

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模块的。

撰写回答