Python 3.x my Pyqt PlotWidget中的MousePresseEvent-模拟事件
这是完整的代码库。我试图在图形中模拟鼠标点击,这是self.graph,这是一个plotwidget。我希望鼠标单击在plotrunnable类中发生,因此在我单击graph按钮后,它将自动更新,在睡觉之前,它将模拟单击图形,使其看起来像是自动更新Python 3.x my Pyqt PlotWidget中的MousePresseEvent-模拟事件,python-3.x,qt,pyqt,pyqt5,pyqtgraph,Python 3.x,Qt,Pyqt,Pyqt5,Pyqtgraph,这是完整的代码库。我试图在图形中模拟鼠标点击,这是self.graph,这是一个plotwidget。我希望鼠标单击在plotrunnable类中发生,因此在我单击graph按钮后,它将自动更新,在睡觉之前,它将模拟单击图形,使其看起来像是自动更新 # Form implementation generated from reading ui file 'U:\Embedded Graphics View2.ui' # # Created by: PyQt5 UI code generator
# Form implementation generated from reading ui file 'U:\Embedded Graphics View2.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
import pyqtgraph as pg
import pyodbc as db
import pandas as pd
import time, os
from time import strptime as strptime
from time import mktime as mktime
from time import gmtime, strftime
from pyqtgraph import AxisItem
from datetime import datetime, timedelta
from numpy import ceil
import numpy as np
import sip
os.environ['TZ']='EST'
now=time.asctime(time.localtime())
start_time=time.time()
print('starting at '+now)
def time(date):
if date == '':
return None
else:
datetime = date
pattern = '%Y%m%d %H:%M:%S'
epoch = int(mktime(strptime(datetime, pattern)))
return epoch
def connecttosql():
host='{SQL Server}'
server='SERVER' ######### DEV - WILL CHANGE TO PRODUCTION WHEN DELIVERED
database='DB'
username='user'
password='pass'
try:
cs= 'Driver=%s;Server=%s;Uid=%s;Pwd=%s;Database=%s;' % (host,server, username, password, database)
global conn #### THIS WILL BE USED ON THE QUERY
conn= db.connect(cs)
print ('Connected successfully to '+host+', '+server)
except Exception as e:
print ('Error: ' + str (e))
def testconnection():
cursor=conn.cursor()
try:
cursor.execute("SELECT VERSION()")
res=cursor.fetchone()
print(res)
ver=res[0]
if ver in None:
return False
else:
return True
except:
print ("ERROR IN CONNECTION")
return False
def closeconnection():
conn.close
print('CONNECTION WITH DATABASE HAS BEEN CLOSED')
def query(ticker,interval,ST,ET):
# target='U:/py/sql csv/'+ticker+' - '+interval+'.csv'
global conn
table = 'BAR_BB' ### hard code
qry = f"SELECT * FROM {table} WHERE SY = {ticker} AND IL = {interval} AND ST >= {ST} AND ST <= {ET}"
df=pd.read_sql(qry,conn) ###### format will change
df.set_index('ST',inplace=True)
#df.to_csv(target,encoding='utf-8',index=False)
st=df.index.tolist()
op=df['O'].tolist()
hi=df['H'].tolist()
lo=df['L'].tolist()
cl=df['C'].tolist()
bars=[]
x=0
for i in st:
bar=[st[x],op[x],cl[x],lo[x],hi[x]]
bars.append(bar)
x=x+1
data=bars
return data
##Picture that goes in the UI
class CandlestickItem(pg.GraphicsObject):
def __init__(self):
pg.GraphicsObject.__init__(self)
self.flagHasData = False
@QtCore.pyqtSlot(list)
def set_data(self, data):
self.data = data
self.flagHasData = True
self.generatePicture()
self.informViewBoundsChanged()
def generatePicture(self):
## pre-computing a QPicture object allows paint() to run much more quickly,
## rather than re-drawing the shapes every time.
self.picture = QtGui.QPicture()
p = QtGui.QPainter(self.picture)
p.setPen(pg.mkPen('w'))
w = (self.data[1][0] - self.data[0][0]) / 3.
for (t, open, close, min, max) in self.data:
p.drawLine(QtCore.QPointF(t, min), QtCore.QPointF(t, max))
if open > close:
p.setBrush(pg.mkBrush('r'))
else:
p.setBrush(pg.mkBrush('g'))
p.drawRect(QtCore.QRectF(t-w, open, w*2, close-open))
p.end()
def paint(self, p, *args):
p.drawPicture(0, 0, self.picture)
def boundingRect(self):
## boundingRect _must_ indicate the entire area that will be drawn on
## or else we will get artifacts and possibly crashing.
## (in this case, QPicture does all the work of computing the bouning rect for us)
return QtCore.QRectF(self.picture.boundingRect())
class DateAxisItem(AxisItem):
"""
A tool that provides a date-time aware axis. It is implemented as an
AxisItem that interpretes positions as unix timestamps (i.e. seconds
since 1970).
The labels and the tick positions are dynamically adjusted depending
on the range.
It provides a :meth:`attachToPlotItem` method to add it to a given
PlotItem
"""
# Max width in pixels reserved for each label in axis
_pxLabelWidth = 80
def __init__(self, *args, **kwargs):
AxisItem.__init__(self, *args, **kwargs)
self._oldAxis = None
def tickValues(self, minVal, maxVal, size):
"""
Reimplemented from PlotItem to adjust to the range and to force
the ticks at "round" positions in the context of time units instead of
rounding in a decimal base
"""
maxMajSteps = int(size/self._pxLabelWidth)
dt1 = datetime.fromtimestamp(minVal)
dt2 = datetime.fromtimestamp(maxVal)
dx = maxVal - minVal
majticks = []
if dx > 63072001: # 3600s*24*(365+366) = 2 years (count leap year)
d = timedelta(days=366)
for y in range(dt1.year + 1, dt2.year):
dt = datetime(year=y, month=1, day=1)
majticks.append(mktime(dt.timetuple()))
elif dx > 5270400: # 3600s*24*61 = 61 days
d = timedelta(days=31)
dt = dt1.replace(day=1, hour=0, minute=0,
second=0, microsecond=0) + d
while dt < dt2:
# make sure that we are on day 1 (even if always sum 31 days)
dt = dt.replace(day=1)
majticks.append(mktime(dt.timetuple()))
dt += d
elif dx > 172800: # 3600s24*2 = 2 days
d = timedelta(days=1)
dt = dt1.replace(hour=0, minute=0, second=0, microsecond=0) + d
while dt < dt2:
majticks.append(mktime(dt.timetuple()))
dt += d
elif dx > 7200: # 3600s*2 = 2hours
d = timedelta(hours=1)
dt = dt1.replace(minute=0, second=0, microsecond=0) + d
while dt < dt2:
majticks.append(mktime(dt.timetuple()))
dt += d
elif dx > 1200: # 60s*20 = 20 minutes
d = timedelta(minutes=10)
dt = dt1.replace(minute=(dt1.minute // 10) * 10,
second=0, microsecond=0) + d
while dt < dt2:
majticks.append(mktime(dt.timetuple()))
dt += d
elif dx > 120: # 60s*2 = 2 minutes
d = timedelta(minutes=1)
dt = dt1.replace(second=0, microsecond=0) + d
while dt < dt2:
majticks.append(mktime(dt.timetuple()))
dt += d
elif dx > 20: # 20s
d = timedelta(seconds=10)
dt = dt1.replace(second=(dt1.second // 10) * 10, microsecond=0) + d
while dt < dt2:
majticks.append(mktime(dt.timetuple()))
dt += d
elif dx > 2: # 2s
d = timedelta(seconds=1)
majticks = range(int(minVal), int(maxVal))
else: # <2s , use standard implementation from parent
return AxisItem.tickValues(self, minVal, maxVal, size)
L = len(majticks)
if L > maxMajSteps:
majticks = majticks[::int(ceil(float(L) / maxMajSteps))]
return [(d.total_seconds(), majticks)]
def tickStrings(self, values, scale, spacing):
"""Reimplemented from PlotItem to adjust to the range"""
ret = []
if not values:
return []
if spacing >= 31622400: # 366 days
fmt = "%Y"
elif spacing >= 2678400: # 31 days
fmt = "%Y %b"
elif spacing >= 86400: # = 1 day
fmt = "%b/%d"
elif spacing >= 3600: # 1 h
fmt = "%b/%d-%Hh"
elif spacing >= 60: # 1 m
fmt = "%H:%M"
elif spacing >= 1: # 1s
fmt = "%H:%M:%S"
else:
# less than 2s (show microseconds)
# fmt = '%S.%f"'
fmt = '[+%fms]' # explicitly relative to last second
for x in values:
try:
t = datetime.fromtimestamp(x)
ret.append(t.strftime(fmt))
except ValueError: # Windows can't handle dates before 1970
ret.append('')
return ret
def attachToPlotItem(self, plotItem):
"""Add this axis to the given PlotItem
:param plotItem: (PlotItem)
"""
self.setParentItem(plotItem)
viewBox = plotItem.getViewBox()
self.linkToView(viewBox)
self._oldAxis = plotItem.axes[self.orientation]['item']
self._oldAxis.hide()
plotItem.axes[self.orientation]['item'] = self
pos = plotItem.axes[self.orientation]['pos']
plotItem.layout.addItem(self, *pos)
self.setZValue(-1000)
def detachFromPlotItem(self):
"""Remove this axis from its attached PlotItem
(not yet implemented)
"""
raise NotImplementedError() # TODO
class TimeAxisItem(pg.AxisItem):
def tickStrings(self, values, scale, spacing):
return [datetime.fromtimestamp(value) for value in values]
##UI SetUP
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1442, 1018)
MainWindow.setAutoFillBackground(False)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.graphicsView = QtWidgets.QWidget(self.centralwidget)
self.flagHasData = False
self.graphicsView.setGeometry(QtCore.QRect(0, 0, 1201, 991))
font = QtGui.QFont()
font.setPointSize(18)
self.graphicsView.setFont(font)
brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
self.graphicsView.setObjectName("graphicsView")
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setEnabled(True)
self.lineEdit.setGeometry(QtCore.QRect(1280, 20, 151, 21))
font = QtGui.QFont()
font.setPointSize(11)
self.lineEdit.setFont(font)
self.lineEdit.setObjectName("lineEdit")
self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit_2.setGeometry(QtCore.QRect(1280, 80, 151, 20))
font = QtGui.QFont()
font.setPointSize(11)
self.lineEdit_2.setFont(font)
self.lineEdit_2.setText("")
self.lineEdit_2.setObjectName("lineEdit_2")
self.lineEdit_3 = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit_3.setGeometry(QtCore.QRect(1280, 160, 151, 20))
font = QtGui.QFont()
font.setPointSize(11)
self.lineEdit_3.setFont(font)
self.lineEdit_3.setObjectName("lineEdit_3")
self.lineEdit_4 = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit_4.setGeometry(QtCore.QRect(1280, 230, 151, 20))
font = QtGui.QFont()
font.setPointSize(11)
self.lineEdit_4.setFont(font)
self.lineEdit_4.setObjectName("lineEdit_4")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(1280, 0, 91, 16))
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(1280, 60, 111, 16))
self.label_2.setObjectName("label_2")
self.label_3 = QtWidgets.QLabel(self.centralwidget)
self.label_3.setGeometry(QtCore.QRect(1280, 120, 51, 16))
self.label_3.setObjectName("label_3")
self.label_4 = QtWidgets.QLabel(self.centralwidget)
self.label_4.setGeometry(QtCore.QRect(1280, 190, 101, 16))
self.label_4.setObjectName("label_4")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(1280, 260, 75, 23))
self.pushButton.setObjectName("pushButton")
self.label_5 = QtWidgets.QLabel(self.centralwidget)
self.label_5.setGeometry(QtCore.QRect(1280, 140, 170, 20))
self.label_5.setObjectName("label_5")
self.label_6 = QtWidgets.QLabel(self.centralwidget)
self.label_6.setGeometry(QtCore.QRect(1280, 210, 170, 20))
self.label_6.setObjectName("label_6")
self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_2.setGeometry(QtCore.QRect(1360, 260, 75, 23))
self.pushButton_2.setObjectName("pushButton_2")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.pushButton.clicked.connect(self.btn_click)
self.pushButton_2.clicked.connect(self.clear)
self.main_layout = QtWidgets.QHBoxLayout()
self.graphicsView.setLayout(self.main_layout)
self.graph = None
self.glayout = None
self.data = []
self.vb = None
self.main_layout.addWidget(self.graph)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
##renaming all the Labels and Window
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Graph Interface"))
self.label.setText(_translate("MainWindow", "Ticker (Bloomberg)"))
self.label_2.setText(_translate("MainWindow", "Interval (In Seconds)"))
self.label_3.setText(_translate("MainWindow", "Start Time"))
self.label_4.setText(_translate("MainWindow", "End Time (Optional)"))
self.pushButton.setText(_translate("MainWindow", "Graph"))
self.label_5.setText(_translate("MainWindow", "YYYYMMDD 00:00:00 (UTC)"))
self.label_6.setText(_translate("MainWindow", "YYYYMMDD 00:00:00 (UTC)"))
self.pushButton_2.setText(_translate("MainWindow", "Clear"))
global mouse_click_event
def mouse_click_event(self):
graph.clicked()
#Button Click function.
def btn_click(self):
global ticker, interval, start_time, end_time, graph
global DRAW_GRAPH
connecttosql()
self.data = [ ## fields are (time, open, close, min, max).
(1., 10, 13, 5, 15),
(2., 13, 17, 9, 20),
(3., 17, 14, 11, 23),
(4., 14, 15, 5, 19),
(5., 15, 9, 8, 22),
(6., 9, 15, 8, 16)]
self.graph = pg.PlotWidget(name = 'Whatever', aixsItems = {'bottom' : TimeAxisItem(orientation = 'bottom')})
# self.ticker = self.lineEdit.text()
#self.interval = self.lineEdit_2.text()
#self.start_time = time(self.lineEdit_3.text())
#self.end_time = time(self.lineEdit_4.text())
# if self.end_time == None:
# self.end_time = time(strftime("%Y%m%d %H:%M:%S", gmtime()))
# else:
# self.end_time = time((self.lineEdit_4.text()))
# self.ticker = "'{}'".format(self.ticker)
# self.interval = "'{}'".format(self.interval)
# ticker = self.ticker
# interval = self.interval
# start_time = self.start_time
# end_time = self.end_time
self.glayout = pg.GraphicsLayout()
self.vb = self.glayout.addViewBox()
self.vb.enableAutoRange(axis='xy',enable = True)
#self.data = query(self.ticker,self.interval,self.start_time,self.end_time)
self.item = CandlestickItem()
self.item.set_data(self.data)
self.graph.addItem(self.item)
self.axis1 = DateAxisItem(orientation = 'bottom')
self.axis1.attachToPlotItem(self.graph.getPlotItem())
self.graph.showGrid(y=True, alpha = 0.8)
self.main_layout.addWidget(self.graph)
runnable = PlotRunnable(self.item)
QtCore.QThreadPool.globalInstance().start(runnable)
def clear(self):
self.parent = self.graph.parent()
self.graph.setParent(None)
self.graph.setParent(self.parent)
class PlotRunnable(QtCore.QRunnable):
def __init__(self, it):
QtCore.QRunnable.__init__(self)
self.it = it
def run(self):
while True:
data = self.it.data
# end_time = end_time = time(strftime("%Y%m%d %H:%M:%S", gmtime()))
rand =[ ## fields are (time, open, close, min, max).
(1., 10, 13, 5, 15),
(2., 13, 17, 9, 20),
(3., 17, 14, 11, 23),
(4., 14, 15, 5, 19),
(5., 15, 9, 8, 22),
(6., 9, 15, 8, 16),
(7., 8, 16, 10, 17)]
new_bar = rand[-1]
data.append(new_bar)
QtCore.QMetaObject.invokeMethod(self.it, "set_data",
QtCore.Qt.QueuedConnection,
QtCore.Q_ARG(list, data))
#put mouse click here
print("ran")
#interval = int("{}".format(interval))
QtCore.QThread.msleep(1000)
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
if __name__ == '__main__':
import sys
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
您的问题是什么?在SOSimualte中,在qthread.msleep发生之前单击鼠标,请求帮助不是有效的问题。只有当你点击它时,图表才会更新,所以我想如果我可以自动点击鼠标,它会给它自动更新的外观错误可能在别处,但我无法告诉你它在哪里,因为你的代码是不可验证的,如果你想帮助提供一个@eyllanesc上传的可验证示例。我相信这是完全正确的。不是很小。@eyllanesc你有没有可能想出一个解决办法?