2014-11-15 22 views
0

您好,我是python和PySide的新成员,经过数小时的研究后,我尝试开发一个简单的GUI来显示API服务的一些数据。Python + Pyside + QThreads发出信号和分段错误

我的程序是“简单的”,我实现了Qthread,并有工作线程向api发出请求,并以QObject作为参数向主线程发出信号。

主线程收到信号并更新GUI。

问题是我运行程序时出现分段错误错误。

在实现api请求之前,我尝试简单地传递一个数字作为字符串,并且完美地工作。

我想我的错误出现在我的主线程尝试访问GObject并且我的工作线程也尝试访问该对象时。

继承人我的代码:

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

import sys 
from PySide import QtGui 
from PySide import QtCore 
import urllib2 
import json 
import datetime 
import time 
from termcolor import colored 
from blessings import Terminal 


class MySig(QtCore.QObject): 
    sig = QtCore.Signal(QtCore.QObject) 

class MyThread(QtCore.QThread): 

    def __init__(self, parent=None): 
     QtCore.QThread.__init__(self, parent) 
     self.exiting = 10 
     self.signal = MySig() 


    def callAping(self, jsonrpc_req): 
     url = "https://api.betfair.com/exchange/betting/json-rpc/v1" 
     headers = { 'X-Application' : '***********', 'X-Authentication' : '**************************' ,'content-type' : 'application/json' } 
     try: 
      req = urllib2.Request(url, jsonrpc_req, headers) 
      response = urllib2.urlopen(req) 
      jsonResponse = response.read() 
      return jsonResponse 
     except urllib2.URLError: 
      print 'Oops no service available at ' + str(url) 
      exit() 
     except urllib2.HTTPError: 
      print 'Oops not a valid operation from the service ' + str(url) 
      exit() 

    def getMarketBookBestOffers(self): 

     marketId = "1.116260985" 
     market_book_req = '{"jsonrpc": "2.0", "method": "SportsAPING/v1.0/listMarketBook", "params": {"marketIds":["' + marketId + '"],"priceProjection":{"priceData":["EX_BEST_OFFERS"]}}, "id": 1}' 
     """ 
     print market_book_req 
     """ 
     market_book_response = self.callAping(market_book_req) 
     """ 
     print market_book_response 
     """ 
     market_book_loads = json.loads(market_book_response) 
     try: 
      market_book_result = market_book_loads['result'] 
      return market_book_result 
     except: 
      print 'Exception from API-NG' + str(market_book_result['error']) 
      exit() 


    def run(self): 
     while True: 
      market_book_result = self.getMarketBookBestOffers() 
      self.signal.sig.emit(market_book_result) 
      time.sleep(0.5) 


class Example(QtGui.QWidget): 

    def __init__(self): 
     super(Example, self).__init__() 
     self.initUI() 


    def initUI(self): 

     self.selid1 = QtGui.QLabel('id', self) 
     self.price11 = QtGui.QLabel('0.0', self) 
     self.price12 = QtGui.QLabel('0.0', self) 

     self.hbox1=QtGui.QHBoxLayout() 
     self.hbox1.addWidget(self.selid1) 
     self.hbox1.addWidget(self.price11) 
     self.hbox1.addWidget(self.price12) 

     self.selid2 = QtGui.QLabel('id', self) 
     self.price21 = QtGui.QLabel('0.0', self) 
     self.price22 = QtGui.QLabel('0.0', self) 

     self.hbox2=QtGui.QHBoxLayout() 
     self.hbox2.addWidget(self.selid2) 
     self.hbox2.addWidget(self.price21) 
     self.hbox2.addWidget(self.price22) 

     self.selid3 = QtGui.QLabel('id', self) 
     self.price31 = QtGui.QLabel('0.0', self) 
     self.price32 = QtGui.QLabel('0.0', self) 

     self.hbox3=QtGui.QHBoxLayout() 
     self.hbox3.addWidget(self.selid3) 
     self.hbox3.addWidget(self.price31) 
     self.hbox3.addWidget(self.price32) 

     self.vbox=QtGui.QVBoxLayout() 
     self.vbox.addLayout(self.hbox1) 
     self.vbox.addLayout(self.hbox2) 
     self.vbox.addLayout(self.hbox3) 

     self.setLayout(self.vbox) 

     self.setGeometry(300, 300, 400, 250) 
     self.setWindowTitle('Absolute') 

     self.thread = MyThread() 
     self.thread.start() 
     self.thread.signal.sig.connect(self.changelabel) 

    def changelabel(self, datas):  
     if(datas is not None): 
      for marketBook in datas: 
       runners = marketBook['runners'] 
       if (runners[0]['status'] == 'ACTIVE'): 
        self.selid1.setText(runners[0]['status']) 
        self.price11.setText(str(runners[0]['ex']['availableToBack'][0]['price'])) 
        self.price12.setText(str(runners[0]['ex']['availableToLay'][0]['price'])) 
       else: 
        self.selid1.setText(runners[0]['status']) 

       if (runners[1]['status'] == 'ACTIVE'): 
        self.selid2.setText(runners[1]['status']) 
        self.price21.setText(str(runners[1]['ex']['availableToBack'][0]['price'])) 
        self.price22.setText(str(runners[1]['ex']['availableToLay'][0]['price'])) 
       else: 
        self.selid2.setText(runners[1]['status']) 

       if (runners[2]['status'] == 'ACTIVE'): 
        self.selid3.setText(runners[2]['status']) 
        self.price31.setText(str(runners[2]['ex']['availableToBack'][0]['price'])) 
        self.price32.setText(str(runners[2]['ex']['availableToLay'][0]['price'])) 
       else: 
        self.selid3.setText(runners[2]['status']) 


def main(): 

    app = QtGui.QApplication(sys.argv) 
    ex = Example() 
    ex.show() 
    sys.exit(app.exec_()) 


if __name__ == '__main__': 
    main() 

对不起,我的英语

回答

0

你不需要MySig类和信号不应被定义为发出QObject,因为不匹配的类型你正在发射的物体。

我不能测试你的示例代码,但试试这个:

class MyThread(QtCore.QThread): 
    sig = QtCore.Signal(object) 

    def __init__(self, parent=None): 
     QtCore.QThread.__init__(self, parent) 
     self.exiting = 10 
    ... 

    def run(self): 
     ... 
     self.sig.emit(market_book_result) 
    ... 

class Example(QtGui.QWidget): 
    ... 
    def initUI(self):  
     ... 
     self.thread = MyThread() 
     self.thread.sig.connect(self.changelabel) 
     self.thread.start() 
+0

您好感谢这就是解决我的问题。 但问题在哪里?当我试图宣布我的信号? 如果我在连接信号之前启动线程是错误的?我会失去一些发射信号吗? 再次感谢 – asa

+0

@asa。我认为问题在于信号的声明(即使用'QObject'而不是'object')。但是你可以轻松地测试每种可能性以确保。 – ekhumoro

相关问题