I have a Tree View that I need popular with data obtained in a thread, but if I do it apart from it the program has several random problems and errors. Searching I found that the ideal is to trigger a signal from within the thread to be called a function that populates the tree view. So I created a button and connected the 'clicked' signal to the function that spares the tree view, and within the thread I 'emit' the clicked signal of that button. It worked perfectly, but I think it's a gambiarra and I'm not happy about it. Is there a more appropriate way to achieve the same result? Or is there a signal that can be issued without the need to create a widget like I did? Here is a functional summary of my code:
#!/usr/bin/env python3
#-*- coding: utf-8 -*-
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
import requests
import json
import threading
class App(Gtk.Window):
def __init__(self):
super(App, self).__init__()
self.button = Gtk.Button() #botão criado apenas pra usar o sinal 'clicked na thread'
self.button.connect('clicked', self.populate)
self.tree_model = Gtk.ListStore(str, str, float)
treeView = Gtk.TreeView(model = self.tree_model)
cell = Gtk.CellRendererText()
column1 = Gtk.TreeViewColumn('Name', cell, text = 0)
treeView.append_column(column1)
column2 = Gtk.TreeViewColumn('Symbol', cell, text = 1)
treeView.append_column(column2)
column3 = Gtk.TreeViewColumn('Price $', cell, text = 2)
treeView.append_column(column3)
scrolled = Gtk.ScrolledWindow(hexpand = True)
scrolled.add(treeView)
self.set_default_size(500,200)
self.connect('delete-event', Gtk.main_quit)
self.add(scrolled)
self.thread() #Iniciando a thread
self.show_all()
def populate(self, widget):
self.tree_model.append([self.name, self.symbol, self.price])
def get_data(self):
coins = ('streamr-datacoin', 'ereal', 'burst')
for coin in coins:
response = requests.get('https://api.coinmarketcap.com/v1/ticker/{}'.format(coin))
self.name = json.loads(response.text)[0]['name']
self.symbol = json.loads(response.text)[0]['symbol']
self.price = float(json.loads(response.text)[0]['price_usd'])
self.button.emit('clicked') #emitindo sinal para chamar a função populate
def thread(self):
self.th1 = threading.Thread(target=self.get_data)
self.th1.start()
App()
Gtk.main()