pyqt5插槽参数在第一次致电后未更新
我有一个信号,该信号连接到我用来更改matplotlib图上X范围跨度的插槽。当用户更改显示所有跨度的表中的启动X值时,我正在尝试更新跨度。但是,在第一个跨度编辑之后,程序编辑所有内容都好像它们正在编辑相同的跨度,而不是新选择的跨度。运行代码时:
@QtCore.pyqtSlot()
def xStartChanged(xStart, rowVal):
if self.inCounter == 0:
print( "row in start changed: ", rowVal)
print("xStart in start changed: ", xStart)
print(type(xStart))
tagName = self.highlights[xStart].tag
xEnd = self.highlights[xStart].xEnd
xStartNew = int(self.taggingTable.item(rowVal, 1).text())
self.highlights[xStart].highlightObj.remove() #remove old from the plot
del self.highlights[xStart] #remove old from directory
highlightObj = self.Axes.axvspan(xStartNew, xEnd, color = 'blue', alpha = 0.5) #add new to plot
self.highlights[xStartNew] = highlight(tagName, xStartNew, xEnd, highlightObj) #add new to directory
self.taggingTable.clearSelection() #deselect value from table
self.draw_idle()#update plot
self.inCounter = self.inCounter + 1
def onCellSelect():
index = self.taggingTable.selectedIndexes()
if len(index) != 0:
rowVal = index[0].row()
#get the starting adn ending indices so they can be edited.
##deal with empty cell click
if not (self.taggingTable.item(rowVal, 1) is None):
xStart = int(self.taggingTable.item(rowVal, 1).text())
print("row in cell select: ", rowVal)
print("xStart in cell select: ", xStart)
xEnd = int(self.taggingTable.item(rowVal, 2).text())
self.inCounter = 0
#self.taggingTable.itemChanged.connect(lambda state, item = None, xStartVal = xStart, rowValFxn = rowVal: xStartChanged(xStartVal, rowValFxn))
print(type(xStart))
self.taggingTable.itemChanged.connect(lambda item = None, xStart = xStart: xStartChanged(xStart, rowVal))
self.draw_idle()
#self.taggingTable.itemChanged.connect(xEndChanged)
#self.taggingTable.cellDoubleClicked.connect(onCellSelect)
self.taggingTable.selectionModel().selectionChanged.connect(onCellSelect)
self.draw_idle()
我将获得以下输出:(注意:我隐藏了“路径”,因为它与工作有关,对不起
row in cell select: 0
xStart in cell select: 3517
<class 'int'>
row in start changed: 0
xStart in start changed: 3517
<class 'int'>
row in cell select: 1
xStart in cell select: 2801
<class 'int'>
row in start changed: 0
xStart in start changed: 3517
<class 'int'>
Traceback (most recent call last):
File "path", line 314, in <lambda>
self.taggingTable.itemChanged.connect(lambda item = None, xStart = xStart: xStartChanged(xStart, rowVal))
File "path", line 277, in xStartChanged
tagName = self.highlights[xStart].tag
KeyError: 3517
zsh: abort path
。在更改和编辑单元格之后,第一个插槽函数(OnCellSelect)正在读取新的单元格值和XSTART值,但是嵌套的信号插槽连接(XstartChanged)仍将保留在较旧的单元格和XSTART值上。我假设我在某种程度上打电话给它,我没有意识到
编辑
import sys
from PyQt5.QtWidgets import *
from PyQt5 import QtCore
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.widgets as mwidgets
class Window(QMainWindow):
def __init__(self, parent = None):
super(Window, self).__init__(parent)
self.resize(1600, 800)
self.MyUI()
def MyUI(self):
canvas = Canvas(self, width=14, height=12, dpi=100)
canvas.move(0,0)
class Canvas(FigureCanvas):
def __init__(self, parent, width = 14, height = 12, dpi = 100):
Plot = Figure(figsize=(width, height), dpi=dpi)
self.Axes = Plot.add_subplot(111)
self.Axes.set_position([0.05, 0.58, 0.66, 0.55])
self.rowCount = 0
super().__init__(Plot)
self.setParent(parent)
##add all relevant lines to plot
self.Axes.plot([0,1,2,3,4], [3, 4, 5, 6, 7])
self.Axes.set_xlabel('Frame', fontsize = 10)
self.Axes.grid()
self.Axes.set_aspect(1)
Plot.canvas.draw()
#use this object in the dictionary to hold onto all the spans.
class highlight:
def __init__(self, tag, xStart, xEnd, highlightObj):
self.tag = tag
self.xStart = xStart
self.xEnd = xEnd
self.highlightObj = highlightObj
self.highlights = {} #empty dictionary to store all the tags.
##define a table to hold the values postselection
self.taggingTable = QTableWidget(self)
self.taggingTable.setColumnCount(3)
self.taggingTable.setRowCount(100)
self.taggingTable.setGeometry(QRect(1005,85, 330, 310))
self.taggingTable.setHorizontalHeaderLabels(['Behavior','Start Frame', 'End Frame'])
##highlighting adds a highlight item to the directory.
def onHighlight(xStart, xEnd):
tagName = "No Tag"
self.taggingTable.setItem(self.rowCount, 0, QTableWidgetItem(tagName))
self.taggingTable.setItem(self.rowCount, 1, QTableWidgetItem(str(int(xStart))))
self.taggingTable.setItem(self.rowCount, 2, QTableWidgetItem(str(int(xEnd))))
self.rowCount = self.rowCount + 1
highlightObj = self.Axes.axvspan(xStart, xEnd, color = 'blue', alpha = 0.5)
self.highlights[int(xStart)] = highlight(tagName, xStart, xEnd, highlightObj)
self.draw_idle()
self.span = mwidgets.SpanSelector(self.Axes, onHighlight, "horizontal",
interactive = True, useblit=True, props=dict(alpha=0.5, facecolor="blue"),)
self.draw_idle()
##TODO: editing spans in table is reflected in plot --- use axvspan to track spans? and spanselector to draw them?
##define workflow for when a cell is selected
def xStartChanged(xStart, rowVal):
if self.inCounter == 0:
print( "row in start changed: ", rowVal)
print("xStart in start changed: ", xStart)
xEnd = self.highlights[xStart].xEnd
xStartNew = int(self.taggingTable.item(rowVal, 1).text())
self.highlights[xStart].highlightObj.remove() #remove old from the plot
del self.highlights[xStart] #remove old from directory
highlightObj = self.Axes.axvspan(xStartNew, xEnd, color = 'blue', alpha = 0.5) #add new to plot
self.highlights[xStartNew] = highlight("No tagName", xStartNew, xEnd, highlightObj) #add new to directory
self.taggingTable.clearSelection() #deselect value from table
self.draw_idle()#update plot
self.inCounter = self.inCounter + 1
def onCellSelect():
index = self.taggingTable.selectedIndexes()
if len(index) != 0:
rowVal = index[0].row()
if not (self.taggingTable.item(rowVal, 1) is None):
xStart = int(self.taggingTable.item(rowVal, 1).text())
print("row in cell select: ", rowVal)
print("xStart in cell select: ", xStart)
self.inCounter = 0
self.taggingTable.itemChanged.connect(lambda: xStartChanged(xStart, rowVal))
self.taggingTable.selectionModel().selectionChanged.connect(onCellSelect)
self.draw_idle()
app = QApplication(sys.argv)
window = Window()
window.show()
app.exec()
?
row in cell select: 0
xStart in cell select: 2
row in start changed: 0
xStart in start changed: 2
row in cell select: 1
xStart in cell select: 1
row in start changed: 0
xStart in start changed: 2
Traceback (most recent call last):
File "path", line 103, in <lambda>
self.taggingTable.itemChanged.connect(lambda: xStartChanged(xStart, rowVal))
File "path", line 84, in xStartChanged
xEnd = self.highlights[xStart].xEnd
KeyError: 2
zsh: abort "path"
I have a signal that connects to a slot that I use to change an x-range span on a matplotlib plot. I am trying to update the span when a user changes the starting x value in a table that shows all the spans. However, after the first edit of the span, the proceeding edits all act as though they are editing the same span, rather than the newly selected span. When running the code:
@QtCore.pyqtSlot()
def xStartChanged(xStart, rowVal):
if self.inCounter == 0:
print( "row in start changed: ", rowVal)
print("xStart in start changed: ", xStart)
print(type(xStart))
tagName = self.highlights[xStart].tag
xEnd = self.highlights[xStart].xEnd
xStartNew = int(self.taggingTable.item(rowVal, 1).text())
self.highlights[xStart].highlightObj.remove() #remove old from the plot
del self.highlights[xStart] #remove old from directory
highlightObj = self.Axes.axvspan(xStartNew, xEnd, color = 'blue', alpha = 0.5) #add new to plot
self.highlights[xStartNew] = highlight(tagName, xStartNew, xEnd, highlightObj) #add new to directory
self.taggingTable.clearSelection() #deselect value from table
self.draw_idle()#update plot
self.inCounter = self.inCounter + 1
def onCellSelect():
index = self.taggingTable.selectedIndexes()
if len(index) != 0:
rowVal = index[0].row()
#get the starting adn ending indices so they can be edited.
##deal with empty cell click
if not (self.taggingTable.item(rowVal, 1) is None):
xStart = int(self.taggingTable.item(rowVal, 1).text())
print("row in cell select: ", rowVal)
print("xStart in cell select: ", xStart)
xEnd = int(self.taggingTable.item(rowVal, 2).text())
self.inCounter = 0
#self.taggingTable.itemChanged.connect(lambda state, item = None, xStartVal = xStart, rowValFxn = rowVal: xStartChanged(xStartVal, rowValFxn))
print(type(xStart))
self.taggingTable.itemChanged.connect(lambda item = None, xStart = xStart: xStartChanged(xStart, rowVal))
self.draw_idle()
#self.taggingTable.itemChanged.connect(xEndChanged)
#self.taggingTable.cellDoubleClicked.connect(onCellSelect)
self.taggingTable.selectionModel().selectionChanged.connect(onCellSelect)
self.draw_idle()
I get the following output: (NOTE: I have hidden the "path" because it is work related, sorry.
row in cell select: 0
xStart in cell select: 3517
<class 'int'>
row in start changed: 0
xStart in start changed: 3517
<class 'int'>
row in cell select: 1
xStart in cell select: 2801
<class 'int'>
row in start changed: 0
xStart in start changed: 3517
<class 'int'>
Traceback (most recent call last):
File "path", line 314, in <lambda>
self.taggingTable.itemChanged.connect(lambda item = None, xStart = xStart: xStartChanged(xStart, rowVal))
File "path", line 277, in xStartChanged
tagName = self.highlights[xStart].tag
KeyError: 3517
zsh: abort path
I understand that for some reason, the connection sends the row value and xStart value of 0 and 3517 and after the cell is changed and edited, the first slot function (onCellSelect) is reading the new cell and xStart values, but the nested signal-slot connection (xStartChanged) is still holding onto the older cell and xStart values. I'm assuming that I am calling or initializing it wrong in some way. Is there something i'm not realizing?
EDIT: minimal reproducible example.
import sys
from PyQt5.QtWidgets import *
from PyQt5 import QtCore
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.widgets as mwidgets
class Window(QMainWindow):
def __init__(self, parent = None):
super(Window, self).__init__(parent)
self.resize(1600, 800)
self.MyUI()
def MyUI(self):
canvas = Canvas(self, width=14, height=12, dpi=100)
canvas.move(0,0)
class Canvas(FigureCanvas):
def __init__(self, parent, width = 14, height = 12, dpi = 100):
Plot = Figure(figsize=(width, height), dpi=dpi)
self.Axes = Plot.add_subplot(111)
self.Axes.set_position([0.05, 0.58, 0.66, 0.55])
self.rowCount = 0
super().__init__(Plot)
self.setParent(parent)
##add all relevant lines to plot
self.Axes.plot([0,1,2,3,4], [3, 4, 5, 6, 7])
self.Axes.set_xlabel('Frame', fontsize = 10)
self.Axes.grid()
self.Axes.set_aspect(1)
Plot.canvas.draw()
#use this object in the dictionary to hold onto all the spans.
class highlight:
def __init__(self, tag, xStart, xEnd, highlightObj):
self.tag = tag
self.xStart = xStart
self.xEnd = xEnd
self.highlightObj = highlightObj
self.highlights = {} #empty dictionary to store all the tags.
##define a table to hold the values postselection
self.taggingTable = QTableWidget(self)
self.taggingTable.setColumnCount(3)
self.taggingTable.setRowCount(100)
self.taggingTable.setGeometry(QRect(1005,85, 330, 310))
self.taggingTable.setHorizontalHeaderLabels(['Behavior','Start Frame', 'End Frame'])
##highlighting adds a highlight item to the directory.
def onHighlight(xStart, xEnd):
tagName = "No Tag"
self.taggingTable.setItem(self.rowCount, 0, QTableWidgetItem(tagName))
self.taggingTable.setItem(self.rowCount, 1, QTableWidgetItem(str(int(xStart))))
self.taggingTable.setItem(self.rowCount, 2, QTableWidgetItem(str(int(xEnd))))
self.rowCount = self.rowCount + 1
highlightObj = self.Axes.axvspan(xStart, xEnd, color = 'blue', alpha = 0.5)
self.highlights[int(xStart)] = highlight(tagName, xStart, xEnd, highlightObj)
self.draw_idle()
self.span = mwidgets.SpanSelector(self.Axes, onHighlight, "horizontal",
interactive = True, useblit=True, props=dict(alpha=0.5, facecolor="blue"),)
self.draw_idle()
##TODO: editing spans in table is reflected in plot --- use axvspan to track spans? and spanselector to draw them?
##define workflow for when a cell is selected
def xStartChanged(xStart, rowVal):
if self.inCounter == 0:
print( "row in start changed: ", rowVal)
print("xStart in start changed: ", xStart)
xEnd = self.highlights[xStart].xEnd
xStartNew = int(self.taggingTable.item(rowVal, 1).text())
self.highlights[xStart].highlightObj.remove() #remove old from the plot
del self.highlights[xStart] #remove old from directory
highlightObj = self.Axes.axvspan(xStartNew, xEnd, color = 'blue', alpha = 0.5) #add new to plot
self.highlights[xStartNew] = highlight("No tagName", xStartNew, xEnd, highlightObj) #add new to directory
self.taggingTable.clearSelection() #deselect value from table
self.draw_idle()#update plot
self.inCounter = self.inCounter + 1
def onCellSelect():
index = self.taggingTable.selectedIndexes()
if len(index) != 0:
rowVal = index[0].row()
if not (self.taggingTable.item(rowVal, 1) is None):
xStart = int(self.taggingTable.item(rowVal, 1).text())
print("row in cell select: ", rowVal)
print("xStart in cell select: ", xStart)
self.inCounter = 0
self.taggingTable.itemChanged.connect(lambda: xStartChanged(xStart, rowVal))
self.taggingTable.selectionModel().selectionChanged.connect(onCellSelect)
self.draw_idle()
app = QApplication(sys.argv)
window = Window()
window.show()
app.exec()
I receive the following error:
row in cell select: 0
xStart in cell select: 2
row in start changed: 0
xStart in start changed: 2
row in cell select: 1
xStart in cell select: 1
row in start changed: 0
xStart in start changed: 2
Traceback (most recent call last):
File "path", line 103, in <lambda>
self.taggingTable.itemChanged.connect(lambda: xStartChanged(xStart, rowVal))
File "path", line 84, in xStartChanged
xEnd = self.highlights[xStart].xEnd
KeyError: 2
zsh: abort "path"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论