Приложение wxPython полностью разрывается после обновления библиотеки: wxTextCtrl не работает, диалоговые кнопки сворачиваются - PullRequest
0 голосов
/ 25 сентября 2019

Я сделал приложение, используя wxPython, в Ubuntu 18.04, используя версию из python-wxgtk2.8.Этот пакет больше не доступен после того, как я установил систему из scartch, но это не важно.Теперь я попробовал как python-wxgtk3.0, так и python3-wxgtk4.0 (меняя код только для поддержки Python 3).Внезапно возникают проблемы.

Прежде всего, в wxTextCtrl каретка не видна, хотя я могу печатать.Событие EVT_TEXT также не доставляется, когда я вызываю SetValue() (я использовал это для реализации подсветки синтаксиса).Во-вторых, кнопки, добавленные в настраиваемое диалоговое окно с использованием CreateSeparatedButtonSizer(), имеют высоту ровно 1 пиксель, если их размер можно разрешить с помощью Fit().

Код диалога выглядит следующим образом:

class NewProjectDialog(wx.Dialog):
    def __init__(self, parent):
        wx.Dialog.__init__(self, parent, title="New project...")

        sizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(sizer)

        label = wx.StaticText(self, -1, "Name of the project (as shown in the editor):")
        sizer.Add(label, 0, wx.ALIGN_LEFT|wx.ALL, 2)

        self.ctrlName = wx.TextCtrl(self)
        sizer.Add(self.ctrlName, 0, wx.EXPAND|wx.ALL, 2)

        sizer.Add(wx.StaticText(self, -1, "Project directory (containing the 'configure' file and optinally '.git'):"), 0, wx.ALIGN_LEFT|wx.ALL, 2)
        self.ctrlDir = wx.DirPickerCtrl(self)
        sizer.Add(self.ctrlDir, 0, wx.EXPAND|wx.ALL, 2)

        self.cbInit = wx.CheckBox(self, -1, "Initialize this project with an MBS configuration template")
        sizer.Add(self.cbInit, 0, wx.ALIGN_LEFT|wx.ALL, 2)

        self.chTempl = wx.Choice(self)
        self.chTempl.Disable()
        for label, callback in MBS_TEMPLATES:
            self.chTempl.Append(label, callback)
        self.chTempl.SetSelection(0)

        sizer.Add(self.chTempl, 0, wx.EXPAND|wx.ALL, 2)

        sizer.Add(self.CreateSeparatedButtonSizer(wx.OK | wx.CANCEL), 0, wx.EXPAND|wx.ALL, 2)

        self.Fit()

        self.Bind(wx.EVT_CHECKBOX, self.onInitChange)
        self.Bind(wx.EVT_BUTTON, self.onOK, id = wx.ID_OK)

    def onInitChange(self, e):
        if self.cbInit.IsChecked():
            self.chTempl.Enable()
        else:
            self.chTempl.Disable()

    def onOK(self, e):
        if len(self.ctrlName.GetValue()) == 0:
            wx.MessageBox("Please specify a project name!", "New project", wx.ICON_ERROR)
            return
        elif not os.path.isdir(self.ctrlDir.GetPath()):
            wx.MessageBox("Please specify a project directory!", "New project", wx.ICON_ERROR)
            return
        else:
            path = self.ctrlDir.GetPath()
            if self.cbInit.IsChecked():
                members = os.listdir(path)
                if ".git" in members:
                    members.remove(".git")
                if len(members) != 0:
                    wx.MessageBox("In order to initialize a project, you must point me to an EMPTY directory (or one with only a '.git' folder)!",
                                "New project", wx.ICON_ERROR)
                    return

            e.Skip()

    def getProjectName(self):
        return self.ctrlName.GetValue()

    def getProjectDir(self):
        return self.ctrlDir.GetPath()

    def getInitCallback(self):
        if self.cbInit.IsChecked():
            return self.chTempl.GetClientData(self.chTempl.GetSelection())
        else:
            return None

Это приводит к:

enter image description here

Как вы можете видеть, кнопки OK и Отмена нигде не видны.

Редактор кодаКод виджета следующий:

class CodeEditor(wx.TextCtrl):
    def __init__(self, parent):
        wx.TextCtrl.__init__(self, parent, style=wx.TE_MULTILINE | wx.TE_RICH2 | wx.TE_PROCESS_TAB | wx.TE_PROCESS_ENTER)
        self.SetFont(wx.Font(userConfig["CodeEditor.FontSize"], wx.DEFAULT, wx.NORMAL, wx.NORMAL, False, userConfig["CodeEditor.FontFamily"]))
        self.SetBackgroundColour(wx.Colour(*userConfig["CodeEditor.Background"]))
        self.SetForegroundColour(wx.Colour(*userConfig["CodeEditor.Foreground"]))
        self.attrNull = wx.TextAttr(wx.Colour(*userConfig["CodeEditor.Foreground"]))
        self.attrKeyword = wx.TextAttr(wx.Colour(*userConfig["CodeEditor.Syntax.Keyword"]))
        self.attrString = wx.TextAttr(wx.Colour(*userConfig["CodeEditor.Syntax.String"]))
        self.attrNumber = wx.TextAttr(wx.Colour(*userConfig["CodeEditor.Syntax.Number"]))
        self.attrUserType = wx.TextAttr(wx.Colour(*userConfig["CodeEditor.Syntax.UserType"]))
        self.attrComment = wx.TextAttr(wx.Colour(*userConfig["CodeEditor.Syntax.Comment"]))
        self.attrPreprocessor = wx.TextAttr(wx.Colour(*userConfig["CodeEditor.Syntax.Preprocessor"]))
        self.Bind(wx.EVT_TEXT, self.onUpdate)
        self.Bind(wx.EVT_TEXT_ENTER, self.onEnter)
        self.file = None
        self.attrs = {
            "keyword": self.attrKeyword,
            "string": self.attrString,
            "number": self.attrNumber,
            "userType": self.attrUserType,
            "comment": self.attrComment,
            "preprocessor": self.attrPreprocessor
        }
        self.SetValue("No file was selected yet!\nPlease select one from the Navigator.")
        self.Disable()

    def setFile(self, efile):
        content = efile.read()
        if content is not None:
            self.file = efile
            self.Enable()
            self.SetValue(content)

    def onEnter(self, e):
        if self.file is None:
            return

        pos = self.GetInsertionPoint()
        code = self.GetValue()

        before = code[:pos]
        after = code[pos:]

        beforeText, afterText = self.file.getMode().getContextualNewline(before, after)
        self.WriteText(beforeText)
        pos = self.GetInsertionPoint()
        self.WriteText(afterText)
        self.SetInsertionPoint(pos)

    def onUpdate(self, e):
        if self.file is None:
            e.Skip()
            return

        code = self.GetValue()
        toker = Tokenizer(code)
        self.file.getMode().colorize(toker)
        self.file.update(code)

        # clear the current styles
        self.SetStyle(0, self.GetLastPosition(), self.attrNull)

        for startPos, endPos, attr in toker.tokens:
            self.SetStyle(startPos, endPos, self.attrs[attr])

        e.Skip()

SetValue() in setFile(), используемый для запуска события onUpdate().Теперь это не так.И каретка также не появляется.

Какие-нибудь указатели?

РЕДАКТИРОВАТЬ: Кажется, работает следующий код:

class MyMCD(wx.Dialog):
    def __init__(self, parent, message, caption, choices=[]):
        wx.Dialog.__init__(self, parent, -1)
        self.SetTitle(caption)
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.message = wx.StaticText(self, -1, message)
        self.clb = wx.CheckListBox(self, -1, choices=choices)
        self.chbox = wx.CheckBox(self, -1, 'Select all')
        self.btns = self.CreateSeparatedButtonSizer(wx.OK | wx.CANCEL)
        #self.Bind(wx.EVT_CHECKBOX, self.EvtChBox, self.chbox)

        sizer.Add(self.message, 0, wx.ALL | wx.EXPAND, 5)
        sizer.Add(self.clb, 1, wx.ALL | wx.EXPAND, 5)
        sizer.Add(self.chbox, 0, wx.ALL | wx.EXPAND, 5)
        sizer.Add(self.btns, 0, wx.ALL | wx.EXPAND, 5)
        self.SetSizer(sizer)
        self.Fit()

, который был скопирован из примера.Я не могу, однако, увидеть, что он делает по-другому.(И у меня до сих пор нет объяснения отсутствующей карете).

...