Upon pressing a listbox row, a thread is started which:
- Clears the treeview (its liststore)
- Then, adds items to the treeview (or rather its liststore).
The row can be pressed multiple times, meaning it can spawn multiple threads, which may end up running simultaneously.
The issue is that if the row is pressed very quickly multiple times, the treeview ends up with duplicate entries. This is caused by the multiple threads running in parallel, all trying to add the same set of items the treeview.
The solution to this issue would be to only ever allow one instance of the thread running at any time. This could be done by either:
Preventing new thread instances from starting if the thread is currently running
Stop the already running instance of the thread, and only then starting a new one
The problem is that I do not know how to implement either of those solutions.
Code:
class Main(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
self.connect("destroy", Gtk.main_quit)
self.liststore = Gtk.ListStore(str)
self.treeview = Gtk.TreeView()
self.treeview.set_model(self.liststore)
cellrenderertext = Gtk.CellRendererText()
treeviewcolumn = Gtk.TreeViewColumn("Items", cellrenderertext, text=0)
self.treeview.append_column(treeviewcolumn)
self.button = Gtk.Button(label='Button')
box = Gtk.Box()
box.set_orientation(Gtk.Orientation.VERTICAL)
box.add(self.button)
box.add(self.treeview)
self.add(box)
self.button.connect('clicked', self.button_clicked)
def button_clicked(self, widget):
def threaded():
self.liststore.clear()
self.liststore.append(['first_item'])
time.sleep(0.1)
self.liststore.append(['second_item'])
time.sleep(0.1)
self.liststore.append(['third_item'])
threading.Thread(target=threaded, daemon=True).start()
if __name__ == '__main__':
window = Main()
window.show_all()
Gtk.main()
I added the time.sleep(0.1) to simulate the delay between each item being added.
Pressing the button multiple times will result in duplicate entries appearing in the treeview. The expected output is:
first_item
second_item
third_item
However, pressing the button really quickly instead results in:
first_item
third_item
second_item
third_item