python-3.x - 我的 Pyqt PlotWidget 中的 MousePressEvent - 模拟事件
问题描述
这是完整的代码库。我试图在图表中模拟鼠标点击,它是 self.graph,它是一个 plotwidget。我希望鼠标单击发生在 plotrunnable 类中,所以在我单击图形按钮后它会自动更新,并且在睡觉之前它会模拟对图形的单击以使其看起来像是自动更新
# 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_()
解决方案
推荐阅读
- python - 是否可以将 '\vdots' 放在 sympy.Matrix 中?
- gdb - 如何检查断点是否按特定顺序命中?
- php - 我应该使用哪个?Project::select("*") 或 new Project()
- maven - 如何解决我的 BOM 的dependencyManagement 依赖项?
- regex - 使用正则表达式获取特定的连字符字母数字组合
- python - 一种更有效的顺序格式化字符串的方法?
- kdb - KDB 窗口化联接,在两个表的列上具有聚合函数
- matlab - 如何比较 Matlab OptimizationExpression 的?
- javascript - 当我调用我的路线时,为什么我的数组没有正确返回?
- arrays - 用于遍历数组中的项目的按钮操作