Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Using signal/slot transfer data from sub thread to main thread,however,the applicaiton always crash!:(
Forum Updated to NodeBB v4.3 + New Features

Using signal/slot transfer data from sub thread to main thread,however,the applicaiton always crash!:(

Scheduled Pinned Locked Moved Unsolved Qt for Python
pyside2
7 Posts 2 Posters 1.1k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • joweiJ Offline
    joweiJ Offline
    jowei
    wrote on last edited by
    #1

    Hi everyone,
    I am creating an application that create a sub thread to setup data, then send the data to main thread to show by signal/slot, however, the application always crash, here is my code:
    GUI.ui

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>MainWindow</class>
     <widget class="QMainWindow" name="MainWindow">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>800</width>
        <height>600</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>MainWindow</string>
      </property>
      <widget class="QWidget" name="centralwidget">
       <widget class="QPushButton" name="btn_start_">
        <property name="geometry">
         <rect>
          <x>190</x>
          <y>40</y>
          <width>75</width>
          <height>23</height>
         </rect>
        </property>
        <property name="text">
         <string>Start</string>
        </property>
       </widget>
       <widget class="QPushButton" name="btn_exit_">
        <property name="geometry">
         <rect>
          <x>310</x>
          <y>40</y>
          <width>75</width>
          <height>23</height>
         </rect>
        </property>
        <property name="text">
         <string>Exit</string>
        </property>
       </widget>
       <widget class="QPlainTextEdit" name="plainTextEdit">
        <property name="geometry">
         <rect>
          <x>140</x>
          <y>90</y>
          <width>541</width>
          <height>351</height>
         </rect>
        </property>
       </widget>
      </widget>
      <widget class="QMenuBar" name="menubar">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>800</width>
         <height>23</height>
        </rect>
       </property>
      </widget>
      <widget class="QStatusBar" name="statusbar"/>
     </widget>
     <resources/>
     <connections/>
    </ui>
    

    GUI.py

    # -*- coding: utf-8 -*-
    
    ################################################################################
    ## Form generated from reading UI file 'main_window.ui'
    ##
    ## Created by: Qt User Interface Compiler version 5.15.2
    ##
    ## WARNING! All changes made in this file will be lost when recompiling UI file!
    ################################################################################
    
    from PySide2.QtCore import *
    from PySide2.QtGui import *
    from PySide2.QtWidgets import *
    
    
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            if not MainWindow.objectName():
                MainWindow.setObjectName(u"MainWindow")
            MainWindow.resize(800, 600)
            self.centralwidget = QWidget(MainWindow)
            self.centralwidget.setObjectName(u"centralwidget")
            self.btn_start_ = QPushButton(self.centralwidget)
            self.btn_start_.setObjectName(u"btn_start_")
            self.btn_start_.setGeometry(QRect(190, 40, 75, 23))
            self.btn_exit_ = QPushButton(self.centralwidget)
            self.btn_exit_.setObjectName(u"btn_exit_")
            self.btn_exit_.setGeometry(QRect(310, 40, 75, 23))
            self.plainTextEdit = QPlainTextEdit(self.centralwidget)
            self.plainTextEdit.setObjectName(u"plainTextEdit")
            self.plainTextEdit.setGeometry(QRect(140, 90, 541, 351))
            MainWindow.setCentralWidget(self.centralwidget)
            self.menubar = QMenuBar(MainWindow)
            self.menubar.setObjectName(u"menubar")
            self.menubar.setGeometry(QRect(0, 0, 800, 23))
            MainWindow.setMenuBar(self.menubar)
            self.statusbar = QStatusBar(MainWindow)
            self.statusbar.setObjectName(u"statusbar")
            MainWindow.setStatusBar(self.statusbar)
    
            self.retranslateUi(MainWindow)
    
            QMetaObject.connectSlotsByName(MainWindow)
        # setupUi
    
        def retranslateUi(self, MainWindow):
            MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
            self.btn_start_.setText(QCoreApplication.translate("MainWindow", u"Start", None))
            self.btn_exit_.setText(QCoreApplication.translate("MainWindow", u"Exit", None))
        # retranslateUi
    
    

    GUI frame inherited by GUI.py

    # !/usr/bin/env python
    # encoding: utf-8
    # @File    : main_frame_module.py
    # @Time    : 2021/6/16
    # @Author  : qz
    # @Version : 1.0
    # @Email   : weiweiqiao@126.com
    # @License : (C) Copyright 2013-2021
    # @Brief   :
    
    
    from PySide2.QtWidgets import QMainWindow
    from PySide2.QtCore import QThread
    from PySide2.QtCore import QObject
    from PySide2.QtWidgets import QApplication
    from PySide2.QtCore import Slot
    from PySide2.QtCore import Signal
    from pyside2_signal_slot_test.main_window import Ui_MainWindow
    from pyside2_signal_slot_test.manager import Manager
    from pyside2_signal_slot_test.data_module import Data
    
    
    class MainWin(QMainWindow):
        def __init__(self, parent = None):
            QMainWindow.__init__(self, parent)
            self.ui = Ui_MainWindow()
            self.ui.setupUi(self)
    
            self.__thread = QThread()
            self.__manager = Manager()
            self.__init_connect()
    
    
        def __init_connect(self):
            """
            链接信号槽
            Returns: None
    
            """
            # 点击退出程序按钮
            self.ui.btn_exit_.clicked.connect(self.__exit_application)
            # 点击启动按钮
            self.ui.btn_start_.clicked.connect(self.__do)
            self.si_send_do.connect(self.__manager.sl_slot)
            self.__manager.si_send_track.connect(self.__show_data)
            self.__manager.si_stop_sub_thread.connect(self.__sl_stop_sub_thread)
    
    
        def __start_thread(self, obj: QObject, thread: QThread):
            """
            启动子线程
            Args:
                obj: 迁移入子线程中的对象
                thread: 子线程
    
            Returns: None
    
            """
            if not thread.isRunning():
                obj.moveToThread(thread)
                thread.start()
    
    
        @Slot()
        def __exit_application(self):
            QApplication.closeAllWindows()
    
    
        @Slot()
        def __do(self):
            self.__start_thread(self.__manager, self.__thread)
            self.si_send_do.emit()
    
    
        @Slot(Data)
        def __show_data(self, data: Data):
            """
            根据传入的数据在文本框中显示
            Args:
                data: 传入的数据对象
    
            Returns: None
    
            """
            # 获取是否显示标识符
            self.ui.plainTextEdit.appendPlainText(str(data.get_is_show()))
    
    
        @Slot(int)
        def __sl_stop_sub_thread(self, code: int):
            if 0 == code:
                self.__thread.exit()
    
    
        si_send_do = Signal()
    
    

    Manager.py

    # !/usr/bin/env python
    # encoding: utf-8
    # @File    : manager.py
    # @Time    : 2021/6/16
    # @Author  : qz
    # @Version : 1.0
    # @Email   : weiweiqiao@126.com
    # @License : (C) Copyright 2013-2021
    # @Brief   :
    
    
    from PySide2.QtCore import QObject
    from PySide2.QtCore import Slot
    from PySide2.QtCore import Signal
    from pyside2_signal_slot_test.data_module import Data
    
    
    class Manager(QObject):
        def __init__(self):
            super().__init__()
    
    
        @Slot()
        def sl_slot(self):
            """
            生成数据对象,通过信号槽传递数据对象。退出当前线程(子线程)
            Returns: None
    
            """
            # 生成数据对象
            track = Data()
            track.setup_is_show(True)
    
            # 传递数据对象
            self.si_send_track.emit(track)
    
            # 发射信号,退出子线程
            self.si_stop_sub_thread.emit(0)
    
    
        # 传递Data类型数据
        si_send_track = Signal(Data)
        # 结束子线程
        si_stop_sub_thread = Signal(int)
    
    

    Data.py

    # !/usr/bin/env python
    # encoding: utf-8
    # @File    : data_module.py
    # @Time    : 2021/6/14
    # @Author  : qz
    # @Version : 1.0
    # @Email   : weiweiqiao@126.com
    # @License : (C) Copyright 2013-2021
    # @Brief   :
    
    
    from PySide2.QtCore import QObject
    
    
    class Data(QObject):
        def __init__(self):
            super(Data, self).__init__()
            # Dict instance
            self.__dict = {}
            self.__is_show = False
            self.__count = 0
    
    
        def setup_data(self, key: str, value: str):
            """
            更新__dict的数据
            Args:
                key: 关键字
                value: 数据
    
            Returns: None
    
            """
            self.__dict.update(key, value)
    
    
        def get_dict(self):
            return self.__dict
    
    
        def setup_is_show(self, flag: bool):
            self.__is_show = flag
    
    
        def get_is_show(self):
            return self.__is_show
    
    

    Main.py

    # !/usr/bin/env python
    # encoding: utf-8
    # @File    : main.py
    # @Time    : 2021/6/16
    # @Author  : qz
    # @Version : 1.0
    # @Email   : weiweiqiao@126.com
    # @License : (C) Copyright 2013-2021
    # @Brief   :
    
    
    import sys
    from PySide2.QtWidgets import QApplication
    from pyside2_signal_slot_test.main_frame_module import MainWin
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
    
        form = MainWin()
        form.show()
    
        sys.exit(app.exec_())
    
    

    The application is always crashing and show "Process finished with exit code -1073741819 (0xC0000005)"

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by SGaist
      #2

      Hi,

      You should run your application through the debugger to see exactly where it crashes.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      joweiJ 1 Reply Last reply
      0
      • SGaistS SGaist

        Hi,

        You should run your application through the debugger to see exactly where it crashes.

        joweiJ Offline
        joweiJ Offline
        jowei
        wrote on last edited by
        #3

        @SGaist
        thx.
        The crash only in "self.si_send_track.emit(track)" of "def sl_slot(self):" function in Manager.py after start sub thread in "self.__start_thread(self.__manager, self.__thread)" of "def __do(self):" function in GUI.py.
        After comment "self.__start_thread(self.__manager, self.__thread)", the appliction is done well.

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          What if you just print the parameter and nothing else in the slot ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          joweiJ 1 Reply Last reply
          0
          • SGaistS SGaist

            What if you just print the parameter and nothing else in the slot ?

            joweiJ Offline
            joweiJ Offline
            jowei
            wrote on last edited by
            #5

            @SGaist
            thx,I follow your mind.
            I use None instead the parameter of TrackData. the application is well done, I print the instance of TrackData in "sl_slot" function of Manager class, the instance is not None. So I think custom type is the point :)
            I have a question, Qt suggest that register custom type, it is useful in Pyside2?

            1 Reply Last reply
            0
            • joweiJ Offline
              joweiJ Offline
              jowei
              wrote on last edited by
              #6

              I found the application is not crash every time, It is often well when runing the first time. :(

              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                Did you try to run your application through gdb to learn where exactly it crashed ?

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved