spyder
spyder copied to clipboard
accent (non-unicode) characters not working in editor, python or ipython console
Problem Description
dead keys like spanish letters cannot be typed (áéíóú).
What steps reproduce the problem?
- Install python 3.9 in an anaconda enviroment on ubuntu 20.04
- Install spyder 5.3.3 inside the anaconda enviroment, using conda install (default with PyQt5 5.15.7)
- 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.
Also, the bitewise or ( ^ ) is not working.
Hey @Zincr0 and @bw-mutley, thanks for reporting. Unfortunately, I can't reproduce this error (I also use Linux, by the way):
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.
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?
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.
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.
Thanks for the fix, @Zincr0 .
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
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.