Geographic Information Systems Asked on January 25, 2021
I recently wrote a Python script that works with raster data and makes some time-consuming operations. My script uses QThread
to update a QList
and a QProgressBar
and everything works fine if I run the script from PyCharm, the progressbar and the list are updated. Moving the code in a QGIS plugin the gui appears correctly and everything seems to work fine, but if I close and open the plugin again, when I click apply QGIS crashes…
To better understand I wrote a code that reproduce the problem. The gui is a QDialog
with a QListWidget
, a QLineEdit
and a QProgressBar
. After writing a word in the QLineEdit
and clicking on the apply buttom the result should be that the new thread makes a loop using the string and adds every single letter as item in the QListWidget
. In the meantime the progressbar increases and I put a sleep time of 1 second to make it visible. I made use also of a QgsMessageBar
to alert the user if no word are edited in the QLineEdit
. I hope it is enough clear…
Here the gui code:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.gui import QgsMessageBar
import sys, time
class my_worker(QObject):
def __init__(self, word):
QObject.__init__(self)
self.word = word
def run(self):
bar_step = 100/len(self.word)
for i in self.word:
self.emit(SIGNAL("add_item(QString)"), i)
self.emit(SIGNAL("increase_bar(int)"), bar_step)
time.sleep(1)
self.emit(SIGNAL("finished()"))
class my_ui(QDialog):
def __init__(self, parent=None):
"""Constructor."""
super(my_ui, self).__init__(parent)
self.list = QListWidget()
self.messagebar = QgsMessageBar()
input_label = QLabel("Input a word")
self.inputedit = QLineEdit()
self.progress_bar = QProgressBar()
self.progress_bar.setRange(0, 100)
self.progress_bar.setValue(0)
self.button_box = QDialogButtonBox(QDialogButtonBox.Apply | QDialogButtonBox.Close)
layout = QGridLayout()
layout.addWidget(self.messagebar, 0, 0, 1, 4)
layout.addWidget(self.list, 1, 0, 1, 4)
layout.addWidget(input_label, 2, 0)
layout.addWidget(self.inputedit, 2, 1, 1, 3)
layout.addWidget(self.progress_bar, 3, 0, 1, 4)
layout.addWidget(self.button_box, 4, 2, 1, 2)
self.setLayout(layout)
self.connect(self.button_box, SIGNAL("rejected()"), self, SLOT("reject()"))
self.setWindowTitle("Example thread")
def start_worker(self, word):
self.worker = my_worker(word)
self.thread = QThread()
self.worker.moveToThread(self.thread)
self.connect(self.worker, SIGNAL("finished()"), self.workerFinished)
self.connect(self.worker, SIGNAL("add_item(QString)"), self.add_item)
self.connect(self.worker, SIGNAL("increase_bar(int)"), self.increase_bar)
self.thread.started.connect(self.worker.run)
self.thread.start()
def workerFinished(self):
self.progress_bar.setValue(100)
self.worker.deleteLater()
self.thread.quit()
self.thread.wait()
self.thread.deleteLater()
def add_item(self, item):
self.list.addItem(item)
return
def increase_bar(self, bar_step):
self.progress_bar.setValue(self.progress_bar.value() + bar_step)
And here the apply and run methods in the main file of the plugin:
def apply(self):
self.dlg.list.clear()
self.dlg.progress_bar.setValue(0)
if self.dlg.inputedit.text() == "":
self.dlg.messagebar.pushMessage("Missing parameter", 'Please insert a word!',
level=QgsMessageBar.WARNING, duration=2)
return
word = unicode(self.dlg.inputedit.text())
self.dlg.start_worker(word)
def run(self):
"""Run method that performs all the real work"""
self.dlg.list.clear()
self.dlg.inputedit.clear()
self.dlg.progress_bar.setValue(0)
self.dlg.connect(self.dlg.button_box.button(QDialogButtonBox.Apply), SIGNAL("clicked()"), self.apply)
# show the dialog
self.dlg.show()
# Run the dialog event loop
result = self.dlg.exec_()
# See if OK was pressed
if result:
# Do something useful here - delete the line containing pass and
# substitute with your code.
pass
As I said everything works fine but I get two strange behaviours:
QLineEdit
the QgsMessageBar
appears correctly but if I close the QDialog
and I do the same the QgsMessageBar
has two items (1 more, see picture)QLineEdit
after opening the plugin for the second time, clicking on apply QGIS crashes.It seems that closing the Dialog it is not deleted and all the changing done during the first opening are preserved.
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP