Issue
I'm adding a color parameter to the LineBand subclass of QWidget. I've found several examples of how to add additional parameters to a subclass in Python 3 and believe I've followed the advice. Yet, when I call the new version of the class using box = LineBand(self.widget2, color)
, I get the error File "C:/Users/...", line 63, in showBoxes ... box = LineBand(viewport, color) ... TypeError: __init__() takes 2 positional arguments but 3 were given
. But, I'm only calling LineBand with 2 arguments, right? Below is the complete code. I've commented all the sections I've changed. I've also commented out the code that changes the background color of the text in order to see the colored lines more clearly (when they actually are drawn). The background color code works fine.
import sys
from PySide.QtCore import *
from PySide.QtGui import *
db = ((5,8,'A',Qt.darkMagenta),(20,35,'B',Qt.darkYellow),(45,60,'C',Qt.darkCyan)) # added color to db
class TextEditor(QTextEdit):
def __init__(self, parent=None):
super().__init__(parent)
text="This is example text that is several lines\nlong and also\nstrangely broken up and can be\nwrapped."
self.setText(text)
cursor = self.textCursor()
for n in range(0,len(db)):
row = db[n]
startChar = row[0]
endChar = row[1]
id = row[2]
color = row[3] # assign color from db to variable
cursor.setPosition(startChar)
cursor.movePosition(QTextCursor.NextCharacter, QTextCursor.KeepAnchor, endChar-startChar)
#charfmt = cursor.charFormat()
#charfmt.setBackground(QColor(color)) # assign color to highlight (background)
#cursor.setCharFormat(charfmt)
cursor.clearSelection()
self.setTextCursor(cursor)
def getBoundingRect(self, start, end):
cursor = self.textCursor()
cursor.setPosition(end)
last_rect = end_rect = self.cursorRect(cursor)
cursor.setPosition(start)
first_rect = start_rect = self.cursorRect(cursor)
if start_rect.y() != end_rect.y():
cursor.movePosition(QTextCursor.StartOfLine)
first_rect = last_rect = self.cursorRect(cursor)
while True:
cursor.movePosition(QTextCursor.EndOfLine)
rect = self.cursorRect(cursor)
if rect.y() < end_rect.y() and rect.x() > last_rect.x():
last_rect = rect
moved = cursor.movePosition(QTextCursor.NextCharacter)
if not moved or rect.y() > end_rect.y():
break
last_rect = last_rect.united(end_rect)
return first_rect.united(last_rect)
class Window(QWidget):
def __init__(self):
super(Window, self).__init__()
self.edit = TextEditor(self)
layout = QVBoxLayout(self)
layout.addWidget(self.edit)
self.boxes = []
def showBoxes(self):
while self.boxes:
self.boxes.pop().deleteLater()
viewport = self.edit.viewport()
for start, end, id, color in db: # get color too
rect = self.edit.getBoundingRect(start, end)
box = LineBand(viewport, color) # call LineBand with color as argument
box.setGeometry(rect)
box.show()
self.boxes.append(box)
def resizeEvent(self, event):
self.showBoxes()
super().resizeEvent(event)
class LineBand(QWidget):
def __init__(self, color): # define color within __init__
super().__init__(self)
self.color = color
def paintEvent(self, event):
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
painter.setPen(QPen(color, 1.8)) # call setPen with color
painter.drawLine(self.rect().topLeft(), self.rect().bottomRight())
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Window()
window.show()
window.showBoxes()
app.exec_()
sys.exit(app.exec_())
Solution
When a method is not overwritten it will be the same as the implemented method of the parent so if you want it to work you must add those parameters, since these depend many times on the parent a simple way is to use *args
and **kwargs
and pass the new parameter as the first parameter. In addition you must use self.color instead of color since color only exists in the constructor.
class Window(QWidget):
[...]
def showBoxes(self):
while self.boxes:
self.boxes.pop().deleteLater()
viewport = self.edit.viewport()
for start, end, id, color in db: # get color too
rect = self.edit.getBoundingRect(start, end)
box = LineBand(color, viewport) # call LineBand with color as argument
box.setGeometry(rect)
box.show()
self.boxes.append(box)
[...]
class LineBand(QWidget):
def __init__(self, color, *args, **kwargs):
QWidget.__init__(self, *args, **kwargs)
self.color = color
def paintEvent(self, event):
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
painter.setPen(QPen(self.color, 1.8)) # call setPen with color
painter.drawLine(self.rect().topLeft(), self.rect().bottomRight())
Output:
Answered By - eyllanesc
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.