Python - 在PyQt小部件中添加Tkinter图形
我们现在有一个用PyQt写的完全功能的图形用户界面(Gui)。我的搭档写了一个函数,可以在Tkinter中绘制数据图。我的问题是,我们怎么把这两个结合起来,让它们一起工作呢?
这是绘图的函数:
def createGraph(self):
import tkinter as tk
# Send in data as param, OR
#data = [17, 20, 15, 10, 7, 5, 4, 3, 2, 1, 1, 0]
# Recieve data within function
s.send("loadgraph")
inputString = repr(s.recv(MSGSIZE))
#inputString = "-20 15 10 7 5 -4 3 2 1 1 0"
print(inputString)
data = [int(x) for x in inputString.split()]
root = tk.Tk()
root.title("FSPwners")
screen_width = 400
screen_height = 700
screen = tk.Canvas(root, width=screen_width, height=screen_height, bg= 'white')
screen.pack()
# highest y = max_data_value * y_stretch
y_stretch = 15
# gap between lower canvas edge and x axis
y_gap = 350
# stretch enough to get all data items in
x_stretch = 10
x_width = 20
# gap between left canvas edge and y axis
x_gap = 20
for x, y in enumerate(data):
# calculate reactangle coordinates (integers) for each bar
x0 = x * x_stretch + x * x_width + x_gap
y0 = screen_height - (y * y_stretch + y_gap)
x1 = x * x_stretch + x * x_width + x_width + x_gap
y1 = screen_height - y_gap
# draw the bar
print(x0, y0, x1, y1)
if y < 0:
screen.create_rectangle(x0, y0, x1, y1, fill="red")
else:
screen.create_rectangle(x0, y0, x1, y1, fill="green")
# put the y value above each bar
screen.create_text(x0+2, y0, anchor=tk.SW, text=str(y))
root.mainloop()
当这个方法单独运行时,它会弹出一个窗口,显示图表。现在我们想要的是,当我们在当前的Gui中按下一个按钮时,也能弹出这个图表。我们该怎么做呢?如果我们在按钮被点击时直接调用createGraph()
,就会出现错误:unrecognized selector sent to instance x009x...
这是什么问题呢?谢谢!
2 个回答
5
这里有一个PyQt的移植版本:
from PyQt4 import QtCore, QtGui
class Graph(QtGui.QWidget):
def __init__(self, data, parent=None):
QtGui.QWidget.__init__(self, parent)
self._data = data
self.resize(400, 700)
self.setWindowTitle('FSPwners')
self.setAutoFillBackground(True)
self.setBackgroundRole(QtGui.QPalette.Base)
def paintEvent(self, event):
painter = QtGui.QPainter()
painter.begin(self)
screen_width = self.width()
screen_height = self.height()
# highest y = max_data_value * y_stretch
y_stretch = 15
# gap between lower canvas edge and x axis
y_gap = 350
# stretch enough to get all data items in
x_stretch = 10
x_width = 20
# gap between left canvas edge and y axis
x_gap = 20
for x, y in enumerate(self._data):
# calculate reactangle coordinates (integers) for each bar
x0 = x * x_stretch + x * x_width + x_gap
y0 = screen_height - (y * y_stretch + y_gap)
x1 = x0 + x_width
y1 = screen_height - y_gap
if y < 0:
painter.setBrush(QtCore.Qt.red)
else:
painter.setBrush(QtCore.Qt.green)
painter.drawRect(QtCore.QRectF(
QtCore.QPointF(x0, y0), QtCore.QPointF(x1, y1)))
print (x0, y0, x1, y1)
# put the y value above each bar
painter.drawText(x0 + 2, y0 - 2, str(y))
painter.end()
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
# data to be graphed
data = [-20, 15, 10, 7, 5, -4, 3, 2, 1, 1, 0]
window = Graph(data)
window.show()
sys.exit(app.exec_())
4
Qt和Tkinter这两个工具不太好搭配,你可以想象一下——我之前玩过Python的图形工具包,写了一个可以进行四则运算的计算器,这个计算器可以在Qt、GTK或者Tkinter上运行,甚至可以同时显示在这三种工具上。
为了让Tkinter和Qt的版本同时工作,我不得不分开进程,也就是说要在不同的运行实例中启动每个工具包。
你的情况不完全一样,因为Qt的图形界面已经在运行了,但也许可以通过一些变通的方法来解决这个问题。
关于这三个计算器的代码可以在这里找到:
https://web.archive.org/web/20101122232402/http://www.python.org.br/wiki/CalculadoraTkGtkQt