spyder icon indicating copy to clipboard operation
spyder copied to clipboard

accent (non-unicode) characters not working in editor, python or ipython console

Open Zincr0 opened this issue 2 years ago • 8 comments

Problem Description

dead keys like spanish letters cannot be typed (áéíóú).

What steps reproduce the problem?

  1. Install python 3.9 in an anaconda enviroment on ubuntu 20.04
  2. Install spyder 5.3.3 inside the anaconda enviroment, using conda install (default with PyQt5 5.15.7)
  3. Open Spyder, try to type any accented letter or "dead keys"

What is the expected output? What do you see instead?

  • Expected: áéíóú´^

  • Actual output: aeiou

Versions

  • Spyder version: 5.3.3
  • Python version: 3.9.13
  • Qt version: 5.15.4
  • PyQt version: 5.15.7
  • Operating System name/version: Ubuntu 20.04

Edited: "expected", "actual output" and steps.

Zincr0 avatar Oct 04 '22 00:10 Zincr0

Also, the bitewise or ( ^ ) is not working.

bw-mutley avatar Oct 04 '22 13:10 bw-mutley

Hey @Zincr0 and @bw-mutley, thanks for reporting. Unfortunately, I can't reproduce this error (I also use Linux, by the way):

accents

So, unless you're able to narrow down this problem and let us know of a specific way to reproduce it, I'm afraid I'll have to close it.

ccordoba12 avatar Oct 10 '22 17:10 ccordoba12

hi there, @ccordoba12 , thanks for the reply. It is hard to go deeper on this, seens like a dependency problem or specific configuration of PyQt. By the way, spyder 4 works fine on my machine. The only thing I can tell you is that I followed the instructions to install spyder 5 it this bug happened. Could you please recommend any investigation procedure?

bw-mutley avatar Oct 10 '22 21:10 bw-mutley

ok i'm a not a pyqt user, but I managed to create this script that prints the key pressed in a a pyqt text input

import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QMainWindow, QWidget, QLabel, QLineEdit
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtCore import QSize
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QEvent
from PyQt5.QtCore import Qt

keymap = {}
for key, value in vars(Qt).items():
    if isinstance(value, Qt.Key):
        keymap[value] = key.partition('_')[2]

modmap = {
    Qt.ControlModifier: keymap[Qt.Key_Control],
    Qt.AltModifier: keymap[Qt.Key_Alt],
    Qt.ShiftModifier: keymap[Qt.Key_Shift],
    Qt.MetaModifier: keymap[Qt.Key_Meta],
    Qt.GroupSwitchModifier: keymap[Qt.Key_AltGr],
    Qt.KeypadModifier: keymap[Qt.Key_NumLock],
    }

def keyevent_to_string(event):
    sequence = []
    for modifier, text in modmap.items():
        if event.modifiers() & modifier:
            sequence.append(text)
    key = keymap.get(event.key(), event.text())
    if key not in sequence:
        sequence.append(key)
    return '+'.join(sequence)


class EventTypes:
    def __init__(self):
        """Create mapping for all known event types."""
        self.string_name = {}
        for name in vars(QEvent):
            attribute = getattr(QEvent, name)
            if type(attribute) == QEvent.Type:
                self.string_name[attribute] = name

    def as_string(self, event: QEvent.Type) -> str:
        """Return the string name for this event."""
        try:
            return self.string_name[event]
        except KeyError:
            return f"UnknownEvent:{event}"

class textbox_keypress(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("bug test")
        self.mydesign()
        self.evtype = EventTypes()
    # ----------------------------------------------------------------------------------
    def mydesign(self):
        self.textbox = QLineEdit(self)
        self.textbox.setGeometry(10,10,300,30)
        self.textbox.installEventFilter(self)


    def eventFilter(self, source, event):
        eventName = self.evtype.as_string(event.type())
        if eventName not in ["Paint", "WindowActivate", "UpdateLater", "ShowToParent", "PolishRequest",
                             "Leave", "Polish", "Move", "Resize", "Show", "InputMethodQuery", "InputMethodQuery",
                             "MetaCall", "WindowDeactivate", "Enter", "ToolTip", "Hide"]:
            if "Focus" not in eventName and "Mouse" not in eventName and "Hover" not in eventName:
                print(eventName)

        if event.type() in [QEvent.KeyPress, QEvent.KeyRelease] and source is self.textbox:
            #print(event)
            #print(event.key())
            #print(event.modifiers())
            print(keyevent_to_string(event))
            print("***********************************************")
        return super(textbox_keypress, self).eventFilter(source,event)

    # ----------------------------------------------------------------------------------
def main():
    myapp = QApplication(sys.argv)
    mywindow = textbox_keypress()
    mywindow.show()
    sys.exit(myapp.exec_())
if __name__ =="__main__":
    main()

the anaconda pyqt version when trying to type the backtick character ` goes like this:

***********************************************
ShortcutOverride
KeyPress
Dead_Acute
***********************************************
KeyRelease
Dead_Acute
***********************************************

and the anaconda python shows nothing on the text input widget.

the system python3 on the other side

***********************************************
KeyRelease
Dead_Acute
***********************************************
InputMethod
KeyRelease
Dead_Acute
***********************************************

Note that there's no KeyPress, no ShortcutOverride and an extra InputMethod appeared, and the system python shows the backtick just fine on the text input widget.

What does this means? no idea. But it shows that the problem is definitely on the pyqt side.

Zincr0 avatar Oct 13 '22 03:10 Zincr0

Found a workaround:

strace will show that the anaconda's pyqt is looking for locale files in the wrong path (the anaconda enviroment)

openat(AT_FDCWD, "/disk2/mambaforge/envs/py309/share/X11/locale/locale.alias", O_RDONLY) = -1 ENOENT (No such file or directory)

and <env>/share/X11/locale indeed does not exists.

so if we create the parent folder and link the locale system here

mkdir -p /disk2/mambaforge/envs/py309/share/X11
ln -s /usr/share/X11/locale /disk2/mambaforge/envs/py309/share/X11/locale

it will now work.

Zincr0 avatar Oct 13 '22 06:10 Zincr0

Thanks for the fix, @Zincr0 .

bw-mutley avatar Oct 16 '22 21:10 bw-mutley

Hey, I was looking all over for a solution and I found it, thank you very much @Zincr0.

Here is the solution for users who use ArchLinux:

sudo mkdir -p /opt/anaconda/share/X11 sudo ln -s /usr/share/X11/locale /opt/anaconda/share/X11/locale

frankmdv avatar Apr 18 '23 04:04 frankmdv

I ran into the same issue. After spending some time with the workaround mentioned here, I went back to the original installation docs https://docs.spyder-ide.org/current/installation.html#conda-environment and installed the version provided through the conda-forge channel. No issues there.

b-e-n-j-a-m avatar Jan 29 '24 06:01 b-e-n-j-a-m