PyQt5 GUI应用中的关注点。需要使用单独的Qthread进行并发

问题描述 投票:0回答:1

我有一个使用PyQt5库制作的简单GUI窗口。

 `
 import sys, csv, time
 from datetime import datetime
 from time import strftime,localtime
 import threading
 import pandas as pd
 import numpy as np
 from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QLabel, QTextEdit, QInputDialog, QLineEdit
 from PyQt5 import QtCore
 from PyQt5.QtCore import QThread, pyqtSignal
 from PyQt5.QtGui import QIcon
 from PyQt5 import uic
 from trade import trade
 from pyqtgraph import PlotWidget
 import pyqtgraph as pg
 from itertools import islice

class UpdateThread(QThread):
signal = pyqtSignal()
def __init__(self, gui):
    QThread.__init__(self)
    self.gui = gui
def run(self):
    try:
        # timer = pg.QtCore.QTimer()
        # timer.timeout.connect(UI.update_plot(self))
        # timer.start(50)
        while(True):
            self.signal.emit()
            time.sleep(5)
    except Exception as e:
        print(e)

class UI(QMainWindow):
gui = None
p_l = 0.0
display_trades = ''

def __init__(self):
    super(UI, self).__init__()
    global gui
    gui = uic.loadUi('rightside.ui', self)
    self.initUI()
    self.timer_thread = UpdateThread(gui)
    self.timer_thread.signal.connect(self.update_plot)
    self.timer_thread.start()
def initUI(self):
    self.prices = self.read_prices()
    trades = self.get_trades()
    list_trade_prices = trades[0].values.tolist()
    list_trade_sizes = trades[1].values.tolist()
    list_trade_ids = trades[4].drop_duplicates().values.tolist()
    as_floats = np.array(list_trade_prices).astype(np.float)
    self.set_fields(self.prices)
    gui.update_button.clicked.connect(self.on_click)
    gui.cancel_button.clicked.connect(self.on_exit)
    self.show()
def get_trades(self):
    df = pd.DataFrame()
    # Get 50 most recent trades
    trades = islice(trade.get_product_trades(), 192)
    for x in reversed(list(trades)):
        # if x['trade_id'] > last_id:
        if x['side'] == 'buy':
            #more trades that hit the bid force price down
            new_row = {0:x['price'], 1:x['size'], 2:1, 3:time.mktime(datetime.timetuple(datetime.now())), 4:x['trade_id']}
            df = df.append(new_row, ignore_index=True)
            bid_side = True
        else:
            #more trades that hit the offer force force price up
            new_row = {0:x['price'], 1:x['size'], 2:0, 3:time.mktime(datetime.timetuple(datetime.now())), 4:x['trade_id']}
            df = df.append(new_row, ignore_index=True)
    df = df.drop_duplicates([4], keep='last')
    return df
def update_plot(self):
    global gui
    #set results_chart
    trades = UI.get_trades(self)
    list_trade_prices = trades[0].values.tolist()
    last_price = list_trade_prices[-1]
    as_floats = np.array(list_trade_prices).astype(np.float)
    gui.results.setText("{0:,.2f}".format(float(last_price)))
    gui.results_chart.clear()
    gui.results_chart.plot(as_floats)
    gui.statusBar().showMessage('Connected')
    self.monitor_prices(last_price)
    prices = self.read_prices()
    self.set_fields(prices)
def get_open_trades(self, btc):
    sum_buys = 0.0
    open_trades = []
    if float(btc) != 0:
        for i in trade.get_last_fills():
            if i['side'] == 'buy':
                sum_buys += float(i['size'])
                open_trades.append([i['price'], i['size']])
                if sum_buys >= float(btc):
                    break
    return open_trades
def monitor_prices(self, last_price):
    global gui
    date_local = strftime("%A, %d %b %Y %H:%M:%S", localtime())
    stop_enter_price = float(gui.enter_box.toPlainText())
    usd = gui.usd_display.text().replace(',', '')
    btc = gui.btc_display.text()
    trade_amount = ''
    if float(last_price) > stop_enter_price and stop_enter_price != 0.0:
        if float(usd) > 10.00:
            trade_amount = "{0:.2f}".format((float(usd)+(float(btc)*float(last_price)))*0.02718)
            result = trade.buy_market(trade_amount)
            gui.statusBar().showMessage(str(result))
            gui.enter_box.setText('')
            with open('stop_enter.txt', 'w') as enter:
                enter.write('0.0')
            with open('../trades/buys.csv','a') as buys:
                writer = csv.writer(buys)
                writer.writerow([date_local, last_price, trade_amount, result])
    open_trades = self.get_open_trades(btc)
    display_trades = ''
    trade_amount = 0.0
    total_amount = 0.0
    STOP_RATE = 0.02
    if len(open_trades) != 0:
        highest_entry_price = float(open_trades[0][0])
        lowest_entry_price = float(open_trades[0][0])
        #find lowest price and set stop-loss 2% below that and increment it up
        for i,j in enumerate(open_trades):
            difference = (float(last_price) - float(open_trades[i][0]))*float(open_trades[i][1])
            total_amount += difference
            per_diff = str((float(last_price) - float(open_trades[i][0])) / float(open_trades[i][0]))
            display_trades += f'{"{0:.3f}".format(float(per_diff)*100)}%\t'
            gui.statusBar().showMessage(display_trades)
            if  highest_entry_price < float(open_trades[i][0]):
                highest_entry_price = float(open_trades[i][0])
            if  lowest_entry_price > float(open_trades[i][0]):
                lowest_entry_price = float(open_trades[i][0])
            #1R
            if float(per_diff) < -STOP_RATE:
                if float(btc) > 0.001:
                    trade_amount = "{0:.8f}".format(float(j[1]))
                    response = trade.sell_market(trade_amount)
                    with open('stop_loss.txt', 'w') as enter:
                        enter.write('0.0')
                        gui.statusBar().showMessage(str(response))
    if float(last_price) < float(gui.stop_box.toPlainText()):
        if float(btc) > 0.001:
            trade_amount = "{0:.8f}".format(float(btc))
            response = trade.sell_market(trade_amount)
            gui.statusBar().showMessage(str(response))
def on_click(self):
    global gui
    enter_price = gui.enter_box.toPlainText()
    stop_price = gui.stop_box.toPlainText()
    self.write_prices('stop_enter.txt', enter_price)
    self.write_prices('stop_loss.txt', stop_price)
    gui.statusBar().showMessage('Updated Successfully!')
    time.sleep(1.618)
    gui.statusBar().showMessage('')
def on_exit(self):
    sys.exit(0)
def write_disk(self, date_local, current_price, trade_amount, note, response):
   with open('../trades/sells.csv','a') as sells:
       writer = csv.writer(sells)
       writer.writerow([date_local, current_price, trade_amount, note, response])

def take_it(self, risk_reward, btc):
   if float(btc) > 0.001:
       response = trade.sell_market(btc)
       # playsound(path+'/sounds/sellit.mp3')
       write_disk(date_local, current_price, trade_amount, risk_reward, response)

def write_prices(self, file_name, price):
    with open(file_name, 'w') as file:
        file.write(price)
def set_fields(self, prices):
    global gui, p_l
    last_price_data = trade.get_last_price()
    last_price = last_price_data['price']
    last_fill_data = None
    while(True):
        last_fill_data = trade.get_last_fill()
        if 'trade_id' in last_fill_data:
            break
    last_fill = '0.0'
    if last_fill_data['side'] != 'sell':
        last_fill = last_fill_data['price']
    p_l = float(last_price) - float(last_fill)

    gui.enter_box.setText(prices[0])
    gui.stop_box.setText(prices[1])
    gui.results.setText("{0:,.2f}".format(p_l))
    gui.in_price.setText("{0:,.2f}".format(float(last_fill)))
    gui.usd_display.setText("{0:,.2f}".format(float(trade.get_usd())))
    gui.btc_display.setText("{0:,.8f}".format(float(trade.get_btc())))
def read_prices(self):
    content = []
    with open('stop_enter.txt', 'r') as enter:
        stop_enter = enter.readlines()
        content.append(stop_enter[0].rstrip())
    with open('stop_loss.txt', 'r') as stop:
        stop_loss = stop.readlines()
        content.append(stop_loss[0].rstrip())
    return content

 app = QApplication(sys.argv)
 ex = UI()
 app.exec_()

`我不太了解qthreads以及如何使它们工作。并且建议将不胜感激。我只想Updatethread每2秒钟左右调用一次update_plot。以为这很简单,但是这让我头疼。感谢您对我的程序员朋友的帮助。

python user-interface pyqt5 qthread qtimer
1个回答
0
投票

对于某些定时更新,最好使用QTimer及其信号QTimer

timeout
© www.soinside.com 2019 - 2024. All rights reserved.