简体   繁体   中英

Python is crashing while trying to clear combobox in pyqt5

I started today with qt compiler, so I don't have much experience in building gui. My project is about to create dynamic smart check boxes to define axes and at the end to plot several subplots to a figure.

I tried to create dynamic combo boxes that change every time I change my current selection in the combo box. The big issue is that it crash every time i try to change a selection in the combo box.

I tried to use.clear() method but it crash every time I clicked on it.

Edit: I changed the code to make producible code. After clicking on "Load Files", you will be able the combo boxes filled. If you will change the combo box "Choose message" for example, the python crash.

The GUI

# ------------------------------------------------- ----- 
# ---------------------- main.py ------------------- ---- 
# --------------------------------------------- --------- 
from  PyQt5.QtWidgets import *
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.uic import loadUi
from PyQt5.QtCore import pyqtSlot
import threading , os, subprocess, importlib, platform
# Decode_class = 'MAVLinkBinFileDecoder'
# Module = importlib.import_module(Decode_class)




from matplotlib.backends.backend_qt5agg import (NavigationToolbar2QT as NavigationToolbar )

import numpy as np
import random

class MatplotlibWidget(QMainWindow):

    def __init__(self):

        QMainWindow.__init__(self)

        loadUi("gui.ui", self)

        self.setWindowTitle ( "PyQt5 & Matplotlib Example GUI" )
        self.loadfiles = 0
        self.first_run = 0
        self.progressBar.setProperty("value", 0)
        # self.pushButton_load_files.setEnabled(False)
        self.pushButton_add_to_graph.setEnabled(False)
        self.pushButton_choose_xml_file.clicked.connect(self.open_xml_FileNamesDialog)
        self.pushButton_choose_bin_files.clicked.connect(self.open_bin_FileNamesDialog)
        self.pushButton_load_files.clicked.connect(self.load_files)
        self.comboBox_choose_file.currentIndexChanged.connect(self.selectionchange_file)
        self.comboBox_message.currentIndexChanged.connect(self.selectionchange_message)
        self.comboBox_system_id.currentIndexChanged.connect(self.selectionchange_system_id)
        self.pushButton_save_plot.clicked.connect(self.update_graph)
        self.file_to_graph_demo = [({'HEARTBEAT':[{'type':[12],'autopilot':[0]},{'type':[2,2,0],'autopilot':[0,0,0]}], 'CHAMBER_STATUS':[{'time_boot_ms':[1,1,1], 'chamber_num':[1,2,3]}], 'ATTITUDE':[{'test':[0,0,0,],'check':[1,1,1]}, {'test':[0,0,0,],'check':[1,1,1]}, 0 , 0, {'test':[0,0,0,],'check':[1,1,1]}]},'test')]


        self.addToolBar(NavigationToolbar(self .MplWidget.canvas, self))

    @pyqtSlot()
    def open_xml_FileNamesDialog(self):
        self.loadfiles += 1
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        self.filename, _ = QFileDialog.getOpenFileNames(self, "QFileDialog.getOpenFileNames()", "",
                                                "Xml Files (*.xml)", options=options)
        if self.loadfiles == 2:
            self.pushButton_load_files.setEnabled(True)
        self.pushButton_choose_xml_file.setVisible(False)

    @pyqtSlot()
    def open_bin_FileNamesDialog(self):
        self.loadfiles += 1
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        self.list_of_file_paths, _ = QFileDialog.getOpenFileNames(self, "QFileDialog.getOpenFileNames()", "",
                                                "Bin Files (*.bin)", options=options)
        if self.loadfiles == 2:
            self.pushButton_load_files.setEnabled(True)
        self.pushButton_choose_bin_files.setVisible(False)

    @pyqtSlot()
    def load_files(self):
        # parse = Module.Logic_bin_to_mat_parser(self.filename[0])
        # parse.generate_dialect_from_xml()  # Run Mavgenerate xml function
        # value = 19
        # self.progressBar.setProperty("value", value)
        # self.file_to_graph = []
        # for path in self.list_of_file_paths:  # Parse and create Matlab from each bin file
        #     parse.decode_messages(path)
        #     parse.create_dictionary_of_amount_of_messages_by_type()
        #     parse.parse_bin_to_mat()
        #     self.file_to_graph.append((parse.save, parse.file_base_name))
        #     parse.convert_parse_dictionary_to_mat()
        #     value += (100 - 20) / len(self.list_of_file_paths)
        #     self.progressBar.setProperty("value", value)
        # value = 100
        # self.progressBar.setProperty("value", value)
        # self.pushButton_load_files.setVisible(False)
        # self.progressBar.setVisible(False)
        for option in self.file_to_graph_demo:
            self.comboBox_choose_file.addItem(option[1])

    @pyqtSlot()
    def selectionchange_file(self):
        self.first_run += 1
        combobox_enty = self.comboBox_choose_file.currentText()
        self.file_idx = self.comboBox_choose_file.findText(combobox_enty)
        list_of_messages = []
        for message in self.file_to_graph_demo[self.file_idx][0].items():
            list_of_messages.append(message[0])
        if self.first_run >= 1:
            self.comboBox_message.clear()
            self.comboBox_message.addItems(list_of_messages)

    @pyqtSlot()
    def selectionchange_message(self):
        self.first_run += 1
        self.combobox_entry_message = self.comboBox_message.currentText()
        self.message_idx = self.comboBox_message.findText(self.combobox_entry_message)
        list_of_system_ids = []
        count = 0
        for idx, system_id in enumerate(self.file_to_graph_demo[self.file_idx][0][self.combobox_entry_message]):
            if system_id != 0:
                count += 1
                list_of_system_ids.append(str(idx+1))
        if self.first_run >= 2:
            self.comboBox_system_id.clear()
            self.comboBox_system_id.addItems(list_of_system_ids)


    @pyqtSlot()
    def selectionchange_system_id(self):
        self.combobox_entry_system_id = int(self.comboBox_system_id.currentText())-1
        self.system_id_idx = self.comboBox_system_id.findText(str(self.combobox_entry_system_id))
        for field in self.file_to_graph_demo[self.file_idx][0][self.combobox_entry_message][self.system_id_idx]:
            self.comboBox_y_axis.addItem(field)
            self.comboBox_x_axis.addItem(field)


    def update_graph(self):

        fs = 500
        f = random.randint(1, 100)
        ts = 1 / fs
        length_of_signal = 100
        t  =  np . linspace (0, 1, length_of_signal )

        cosinus_signal  =  np . cos ( 2 * np . pi * f * t ) 
        sinus_signal  =  np . sin ( 2 * np . pi * f * t )

        self.MplWidget.canvas.axes.clear()
        self.MplWidget.canvas.axes.plot(t,cosinus_signal)
        self.MplWidget.canvas.axes.plot(t,sinus_signal)
        self.MplWidget.canvas.axes.legend(('cosinus', 'sinus'), loc='upper right')
        self.MplWidget.canvas.axes.set_title(' Cosinus - Sinus Signal')
        self.MplWidget.canvas.draw()

if __name__ == '__main__':
    app=QApplication([])
    app.setStyle('Fusion')
    window=MatplotlibWidget()
    window.show()
    app.exec_()

Your issue seems to be in MatplotlibWidget.selectionchange_system_id() . You are trying to cast the current text of self.comboBox_system_id to an int, but this will cause an exception when the current text can't be converted. This is the case just after self.comboBox_system_id is cleared because at that point the current text of the combi box is an empty string. The easiest way to get around this is to test if the current text can be cast to an integer first before continuing, ie

def selectionchange_system_id(self):
    if self.comboBox_system_id.currentText().isdigit():
        self.combobox_entry_system_id = int(self.comboBox_system_id.currentText())-1
        ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM