Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

[PyQt5] QTableWidget Input crash with wchar_t (specifically, Korean characters)



  • Hi. I'm developing my application with PyQt5.
    I'm using QTableWidget, but when I try to insert Korean characters, it crashes.

    I will describe what's possible and not possible.
    After executing my program, I can click one cell on the QTableWidget.
    And then, If I try to put a korean character with the changed input mode with convert key,
    It crashes.

    However, If I double click one cell on the QTableWidget, the cell edit is activated. And
    I can see the text edit cursor. When it's in the situation, I can write korean characters without crash.

    But, When I just use English, There is no problem like above.

    Is there any way to solve this problem If I click one cell and try to put korean characters?

    Thanks in advance.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Please provide a minimal example that reproduces your situation as well as a source for Korean input.

    By the way:

    • What version of PyQt5 are your using ?
    • On what OS ?
    • What python version ?


  • Hi @SGaist .

    • PyQt5 : 5.14.1
    • Windows 10 1909
    • Python 3.7 (32bit)

    This is the minimal example that reproduces my situation.
    and I noticed that the crash does not happen when I deleted setCellWidget().

    I'm not sure you can have another country keyboard input.
    You need your korean keyboard input to reproduce this crash.

    So to reproduce this situation.

    1. Get the Korean keyboard input
    2. Execute this program
    3. Convert input mode into Korean Input
    4. Click one cell once
    5. put the keyboard input
    6. crash

    As I already said, the program does not crash with English.

    import sys
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    from PyQt5.QtWidgets import *
    
    screenWidth = 800
    screenHeight = 600
    
    def testCallback():
        print("cell changed")
    
    def main():
        # App 초기화
        App = QApplication(sys.argv)
    
        # Window 초기화
        Window = QMainWindow()
        myDesktop = QApplication.desktop()
        rect = myDesktop.screenGeometry()
        Window.setGeometry(rect.width() / 2 - screenWidth / 2, rect.height() / 2 - screenHeight / 2, screenWidth, screenHeight);
        
        Widget = QWidget()
        myLayout = QVBoxLayout(Widget)
        myLabel = QLabel("blah")
        myLayout.addWidget(myLabel)
        myTable = QTableWidget(10, 3)
        
        myTable.setItem(0, 0, QTableWidgetItem(""))
        myTable.setItem(0, 1, QTableWidgetItem(""))
        myTable.setHorizontalHeaderLabels(("테스트1", "테스트2", "기능"))
        myTable.cellChanged.connect(testCallback)
        myLayout.addWidget(myTable)
        myTable.setCellWidget(0, 2, QLabel("hallo"))
    
        Window.setCentralWidget(Widget)
        Window.show()
    
        App.exec_()
    
    if __name__ == "__main__":
        main()
    

    I found the same issue on the Stackoverflow : https://stackoverflow.com/questions/54923039/pyqt5-with-qtablewidget-program-crashes-without-any-exception

    I guess there is some error code on the QTableWidget implementation when handling with UTF-8 input, with the CellWidget added.



  • @chan1123 Your code has an error: The callback that is expected to be callable (function, method, etc.) but instead you pass a string:

    class AddButton(QPushButton):
        def __init__(self, callback, rowIndex):
            super(QPushButton, self).__init__("Add")
            self.rowIndex = rowIndex
            self.clicked.connect(lambda: callback(self))
    
    myTable.setCellWidget(0, 2, AddButton("", 0))
    

    Where:

    callback = ""
    rowIndex = 0
    

    I recommend you to run your code in the console/terminal/CMD since many IDEs do not handle Qt errors correctly.



  • @eyllanesc Okay. I see.
    But, That's not the point in this issue.

    I changed the code like this. It still crashes.

    import sys
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    from PyQt5.QtWidgets import *
    
    screenWidth = 800
    screenHeight = 600
    
    def testCallback():
        print("cell changed")
    
    def main():
        # App 초기화
        App = QApplication(sys.argv)
    
        # Window 초기화
        Window = QMainWindow()
        myDesktop = QApplication.desktop()
        rect = myDesktop.screenGeometry()
        Window.setGeometry(rect.width() / 2 - screenWidth / 2, rect.height() / 2 - screenHeight / 2, screenWidth, screenHeight);
        
        Widget = QWidget()
        myLayout = QVBoxLayout(Widget)
        myLabel = QLabel("blah")
        myLayout.addWidget(myLabel)
        myTable = QTableWidget(10, 3)
        
        myTable.setItem(0, 0, QTableWidgetItem(""))
        myTable.setItem(0, 1, QTableWidgetItem(""))
        myTable.setHorizontalHeaderLabels(("테스트1", "테스트2", "기능"))
        myTable.cellChanged.connect(testCallback)
        myLayout.addWidget(myTable)
        myTable.setCellWidget(0, 2, QLabel("hallo"))
    
        Window.setCentralWidget(Widget)
        Window.show()
    
        App.exec_()
    
    if __name__ == "__main__":
        main()
    

    And I also executed the program on Windows Command line terminal.
    and it does not output anything when it crahses.



  • @chan1123 In Linux with PyQt5 5.14.1 and python 3.8 I don't see that problem. You could indicate the versions of the libraries in your environment.



  • @eyllanesc
    What does "the versions of the libraries" mean?
    My environment is

    • PyQt5 : 5.14.1
    • Windows 10 1909
    • Python 3.7 (32bit)

    you are on the Linux, and I'm on the Windows

    And Did you do my reproduction order? :

    1. Get the Korean keyboard input
    2. Execute this program
    3. Convert input mode into Korean Input
    4. Click one cell once
    5. put the keyboard input
    6. crash

  • Banned

    @chan1123 have you looked into compatibility issues with python 3.7 and pyqt 5 -- I think python 3.8 fixes some of those

    also can you provide an MRE (Minimal Reproducible Example) of your situation so that it can simply copy/paste/run and get the error you are getting -- that way someone trying to help you has what you are actually using versus what they think you might be using -- there might be something in your actual code that someone is not aware of that is associated with this issue. So please help us help you provide an MRE



  • @Denni-0
    Hi. I already wrote the MRE in the previous comment.
    Please, look at the previous comments carefully.

    And Can you give me a link where there is the compatibility issues document?


  • Banned

    Okay I ran your code and cleaned it up and ran that and in neither case could I get the error but then I am not sure I can do Step 1, 3, and 5 --- as I do not have a Korean keyboard --- I did copy/paste the Korean in you code and pasted that into a cell with no issues in both programs --- but could not do this without first typing in a cell and then I could paste over what I typed again in both versions of the program. So if nothing else here is a more python-qt-ish version of your code.

    from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout
    from PyQt5.QtWidgets import QTableWidget, QTableWidgetItem, QLabel
    
    class CentralPanel(QWidget):
        def __init__(self, parent):
            QWidget.__init__(self)
            self.Parent = parent
            #-----
            myLabel = QLabel("blah")
            #-----
            myTable = QTableWidget(10, 3)
            myTable.setHorizontalHeaderLabels(("테스트1", "테스트2", "기능"))
            myTable.cellChanged.connect(self.testCallback)
            myTable.setItem(0, 0, QTableWidgetItem(""))
            myTable.setItem(0, 1, QTableWidgetItem(""))
            myTable.setCellWidget(0, 2, QLabel("hallo"))
            #-----
            myLayout = QVBoxLayout()
            myLayout.addWidget(myLabel)
            myLayout.addWidget(myTable)
            #-----
            self.setLayout(myLayout)
    
        def testCallback(self):
            print("cell changed")
    
    class MainWindow(QMainWindow):
        def __init__(self, ScrnRect):
            QMainWindow.__init__(self)
            ScrnWdth = 800
            ScrnHght = 600
            #-----
            self.setGeometry(ScrnRect.width() / 2 - ScrnWdth / 2, ScrnRect.height() / 2 - ScrnHght / 2, ScrnWdth, ScrnHght);
            #-----
            self.CenterPane = CentralPanel(self)
            self.setCentralWidget(self.CenterPane)
    
    if __name__ == "__main__":
        # App 초기화
        EvntThred = QApplication([])
        ScrnRect = EvntThred.desktop().screenGeometry()
    
        # Window 초기화
        MyWindow = MainWindow(ScrnRect)
        MyWindow.show()
    
        EvntThred.exec_()
    
      # If anyone wants more extensive free help I run an online lab-like classroom-like 
      # message server feel free and drop by you will not be able to post until I clear 
      # you as a student as this prevents spammers so if interested here is the invite
      # https://discord.gg/3D8huKC
    


  • I had the same problem when typing Chinese character in QTableWidget if QTableWidget contain a widget in a cell


Log in to reply