用户可以通过在灰色图片上单击两次来通过此应用程序绘制矩形。但是这个应用程序不保存最后的矩形,而是保存其绘制(更新)一个新的矩形 2 个下一个点。我该如何解决这个问题?我怎样才能保存以前的矩形?
class myQLabel(QLabel):
def __init__(self,parent):
super(myQLabel, self).__init__(parent)
self.x = 0
self.y = 0
self.trafficlines = []
def mousePressEvent(self, QMouseEvent):
#print mode
self.x = QMouseEvent.x()
self.y = QMouseEvent.y()
if self.x != 0 and self.y != 0:
self.trafficlines.append(copy.deepcopy([self.x,self.y]))
print "______"
print self.x
print self.y
print "("+str(mode)+")"
print "______"
def paintEvent(self, QPaintEvent):
super(myQLabel, self).paintEvent(QPaintEvent)
painter = QPainter(self)
if mode == 0:
painter.setPen(QPen(Qt.red,3))
elif mode == 1:
painter.setPen(QPen(Qt.blue,3))
elif mode == 2:
painter.setPen(QPen(Qt.green,3))
elif mode == 3:
painter.setPen(QPen(Qt.magenta,3))
if len(self.trafficlines)%2==1 and len(self.trafficlines)>0:
painter.drawPoint(self.trafficlines[-1][0],self.trafficlines[-1][1])
if len(self.trafficlines)%2==0 and len(self.trafficlines)>0 and mode!=0:
painter.drawLine( self.trafficlines[-2][0],self.trafficlines[-2][1],self.trafficlines[-1][0],self.trafficlines[-1][1] )
if len(self.trafficlines)%2==0 and len(self.trafficlines)>0 and mode==0:
x1=self.trafficlines[-2][0]
y1=self.trafficlines[-2][1]
x2=self.trafficlines[-1][0]
y2=self.trafficlines[-1][1]
painter.drawLine( x1,y1,x1,y2)
painter.drawLine( x1,y2,x2,y2)
painter.drawLine( x2,y2,x2,y1)
painter.drawLine( x2,y1,x1,y1)
self.update()
这是全部代码:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys, os
import copy
mode = 5
class Example(QWidget):
def __init__(self,parent):
super(Example, self).__init__()
self.main_image_name="C:\Python27\project\main_image.png"
self.initUI()
def initUI(self):
File_name = QLabel('Setup file name')
File_name_edit = QLineEdit()
QToolTip.setFont(QFont('SansSerif', 10))
#QMainWindow.statusBar().showMessage('Ready')
self.setGeometry(300, 300, 250, 150)
self.resize(640, 360)
#self.setFixedSize(640, 360)
self.center()
self.main_image = myQLabel(self)
self.main_image.setPixmap(QPixmap(self.main_image_name))
btn = QPushButton("Make setup file")
btn.setToolTip('Press <b>Detect</b> button for detecting objects by your settings')
btn.resize(btn.sizeHint())
btn.clicked.connect(QCoreApplication.instance().quit)
btn_browse = QPushButton("Browse")
btn_browse.clicked.connect(self.browse)
btn_set = QPushButton("Set name")
#fullscreen
#self.main_image.setScaledContents(True)
#just centered
self.main_image.setAlignment(Qt.AlignCenter)
#Layout
box_File_name = QHBoxLayout()
box_File_name.addWidget(File_name)
box_File_name.addWidget(File_name_edit)
box_File_name.addWidget(btn_set)
grid = QGridLayout()
grid.setSpacing(10)
grid.addLayout(box_File_name, 1, 0)
#grid.addWidget(File_name_edit, 1, 1)
grid.addWidget(self.main_image, 2, 0)
grid.addWidget(btn_browse, 3 , 0)
grid.addWidget(btn, 4, 0)
box_number = QVBoxLayout()
number_group=QButtonGroup() # Number group
r0=QRadioButton("Traffic Lights")
number_group.addButton(r0)
r1=QRadioButton("Direction")
number_group.addButton(r1)
r2=QRadioButton("Traffic Lines H")
number_group.addButton(r2)
r3=QRadioButton("Traffic Lines V")
number_group.addButton(r3)
box_number.addWidget(r0)
box_number.addWidget(r1)
box_number.addWidget(r2)
box_number.addWidget(r3)
r0.toggled.connect(self.radio0_clicked)
r1.toggled.connect(self.radio1_clicked)
r2.toggled.connect(self.radio2_clicked)
r3.toggled.connect(self.radio3_clicked)
box_road_sign = QHBoxLayout()
road_sign_label = QLabel('Road signs', self)
road_sign = QComboBox()
road_sign.addItem("None")
road_sign.addItem("ex1")
road_sign.addItem("ex2")
road_sign.addItem("ex3")
road_sign.addItem("ex4")
road_sign.addItem("ex5")
box_road_sign.addWidget(road_sign_label)
box_road_sign.addWidget(road_sign)
grid.addLayout(box_road_sign, 1, 1)
grid.addLayout(box_number, 2, 1)
self.setLayout(grid)
self.show()
def browse(self):
w = QWidget()
w.resize(320, 240)
w.setWindowTitle("Select Picture")
filename = QFileDialog.getOpenFileName(w, 'Open File', '/')
self.main_image_name = filename
self.main_image.setPixmap(QPixmap(self.main_image_name))
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def radio0_clicked(self, enabled):
if enabled:
print("0")
global mode
mode=0
def radio1_clicked(self, enabled):
if enabled:
print("1")
global mode
mode=1
def radio2_clicked(self, enabled):
if enabled:
print("2")
global mode
mode=2
def radio3_clicked(self, enabled):
if enabled:
print("3")
global mode
mode=3
class myQLabel(QLabel):
def __init__(self,parent):
super(myQLabel, self).__init__(parent)
self.x = 0
self.y = 0
self.trafficlines = []
def mousePressEvent(self, QMouseEvent):
#print mode
self.x = QMouseEvent.x()
self.y = QMouseEvent.y()
if self.x != 0 and self.y != 0:
self.trafficlines.append(copy.deepcopy([self.x,self.y]))
print "______"
print self.x
print self.y
print "("+str(mode)+")"
print "______"
def paintEvent(self, QPaintEvent):
super(myQLabel, self).paintEvent(QPaintEvent)
painter = QPainter(self)
if mode == 0:
painter.setPen(QPen(Qt.red,3))
elif mode == 1:
painter.setPen(QPen(Qt.blue,3))
elif mode == 2:
painter.setPen(QPen(Qt.green,3))
elif mode == 3:
painter.setPen(QPen(Qt.magenta,3))
if len(self.trafficlines)%2==1 and len(self.trafficlines)>0:
painter.drawPoint(self.trafficlines[-1][0],self.trafficlines[-1][1])
if len(self.trafficlines)%2==0 and len(self.trafficlines)>0 and mode!=0:
painter.drawLine( self.trafficlines[-2][0],self.trafficlines[-2][1],self.trafficlines[-1][0],self.trafficlines[-1][1] )
if len(self.trafficlines)%2==0 and len(self.trafficlines)>0 and mode==0:
x1=self.trafficlines[-2][0]
y1=self.trafficlines[-2][1]
x2=self.trafficlines[-1][0]
y2=self.trafficlines[-1][1]
painter.drawLine( x1,y1,x1,y2)
painter.drawLine( x1,y2,x2,y2)
painter.drawLine( x2,y2,x2,y1)
painter.drawLine( x2,y1,x1,y1)
self.update()
class menubarex(QMainWindow):
def __init__(self, parent=None):
super(menubarex, self).__init__(parent)
self.form_widget = Example(self)
self.setCentralWidget(self.form_widget)
self.initUI()
def initUI(self):
exitAction = QAction(QIcon('exit.png'), '&Exit', self)
exitAction.setShortcut('Ctrl+Q')
exitAction.setStatusTip('Exit application')
exitAction.triggered.connect(qApp.quit)
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(exitAction)
#self.toolbar = self.addToolBar('Exit')
#self.toolbar.addAction(exitAction)
self.statusBar().showMessage('Ready')
self.setWindowTitle('mi ban')
self.setWindowIcon(QIcon('C:\Python27\project\icon.png'))
def closeEvent(self, event):
reply = QMessageBox.question(self, 'Message',
"Are you sure to quit?", QMessageBox.Yes |
QMessageBox.No)
if reply == QMessageBox.Yes:
event.accept()
else:
event.ignore()
def main():
app = QApplication(sys.argv)
#ex = Example()
menubar = menubarex()
menubar.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
最佳答案
paintEvent()
重新绘制整个小部件,因此它不会节省先前绘制的内存,因此不会保存矩形或先前的线条。解决方案是存储这些状态并再次重新绘制所有内容,为此我们可以将模式和点存储在 trafficlines
中,如下所示:
class myQLabel(QLabel):
def __init__(self,parent):
super(myQLabel, self).__init__(parent)
self.trafficlines = []
self.mode = 0
self.start_point = QPoint()
def setMode(self, mode):
self.mode = mode
def mousePressEvent(self, event):
if self.start_point.isNull():
self.start_point = event.pos()
else:
self.trafficlines.append((self.mode,[self.start_point, event.pos()]))
self.start_point = QPoint()
self.update()
def paintEvent(self, event):
super(myQLabel, self).paintEvent(event)
painter = QPainter(self)
colors = [Qt.red, Qt.blue, Qt.green, Qt.magenta]
for mode, points in self.trafficlines:
painter.setPen(QPen(colors[mode],3))
if mode != 0:
painter.drawLine(*points)
else:
rect = QRect(*points)
painter.drawRect(rect)
if not self.start_point.isNull():
painter.setPen(QPen(colors[self.mode],3))
painter.drawPoint(self.start_point)
<小时/>
注意:不要使用全局变量,它们很难调试,而且会出现不必要的多次。
此外,我还冒昧地改进了您的代码,以更少的行数使其更具可读性。完整的代码如下:
import sys
import os
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class Example(QWidget):
def __init__(self,parent):
super(Example, self).__init__()
self.main_image_name="C:\Python27\project\main_image.png"
self.initUI()
def initUI(self):
File_name = QLabel('Setup file name')
File_name_edit = QLineEdit()
self.resize(640, 360)
self.center()
self.main_image = myQLabel(self)
self.main_image.setPixmap(QPixmap(self.main_image_name))
btn = QPushButton("Make setup file")
btn.setToolTip('Press <b>Detect</b> button for detecting objects by your settings')
btn.resize(btn.sizeHint())
btn.clicked.connect(QCoreApplication.instance().quit)
btn_browse = QPushButton("Browse")
btn_browse.clicked.connect(self.browse)
btn_set = QPushButton("Set name")
self.main_image.setAlignment(Qt.AlignCenter)
#Layout
box_File_name = QHBoxLayout()
box_File_name.addWidget(File_name)
box_File_name.addWidget(File_name_edit)
box_File_name.addWidget(btn_set)
grid = QGridLayout(self)
grid.setSpacing(10)
grid.addLayout(box_File_name, 1, 0)
#grid.addWidget(File_name_edit, 1, 1)
grid.addWidget(self.main_image, 2, 0)
grid.addWidget(btn_browse, 3 , 0)
grid.addWidget(btn, 4, 0)
box_number = QVBoxLayout()
number_group = QButtonGroup(self) # Number group
for i, text in enumerate(["Traffic Lights", "Direction", "Traffic Lines H", "Traffic Lines V"]):
rb = QRadioButton(text)
box_number.addWidget(rb)
number_group.addButton(rb, i)
number_group.buttonClicked[int].connect(self.main_image.setMode)
number_group.button(0).setChecked(True)
box_road_sign = QHBoxLayout()
road_sign_label = QLabel('Road signs', self)
road_sign = QComboBox()
road_sign.addItems(["None", "ex1", "ex2","ex3", "ex4", "ex5"])
box_road_sign.addWidget(road_sign_label)
box_road_sign.addWidget(road_sign)
grid.addLayout(box_road_sign, 1, 1)
grid.addLayout(box_number, 2, 1)
def browse(self):
filename = QFileDialog.getOpenFileName(self, 'Open File', '/')
self.main_image_name = filename
self.main_image.setPixmap(QPixmap(self.main_image_name))
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
class myQLabel(QLabel):
def __init__(self,parent):
super(myQLabel, self).__init__(parent)
self.trafficlines = []
self.mode = 0
self.start_point = QPoint()
def setMode(self, mode):
self.mode = mode
def mousePressEvent(self, event):
if self.start_point.isNull():
self.start_point = event.pos()
else:
self.trafficlines.append((self.mode,[self.start_point, event.pos()]))
self.start_point = QPoint()
self.update()
def paintEvent(self, event):
super(myQLabel, self).paintEvent(event)
painter = QPainter(self)
colors = [Qt.red, Qt.blue, Qt.green, Qt.magenta]
for mode, points in self.trafficlines:
painter.setPen(QPen(colors[mode],3))
if mode != 0:
painter.drawLine(*points)
else:
rect = QRect(*points)
painter.drawRect(rect)
if not self.start_point.isNull():
painter.setPen(QPen(colors[self.mode],3))
painter.drawPoint(self.start_point)
class menubarex(QMainWindow):
def __init__(self, parent=None):
super(menubarex, self).__init__(parent)
self.form_widget = Example(self)
self.setCentralWidget(self.form_widget)
self.initUI()
def initUI(self):
exitAction = QAction(QIcon('exit.png'), '&Exit', self)
exitAction.setShortcut('Ctrl+Q')
exitAction.setStatusTip('Exit application')
exitAction.triggered.connect(qApp.quit)
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(exitAction)
self.statusBar().showMessage('Ready')
self.setWindowTitle('mi ban')
self.setWindowIcon(QIcon('C:\Python27\project\icon.png'))
def closeEvent(self, event):
reply = QMessageBox.question(self, 'Message',
"Are you sure to quit?", QMessageBox.Yes |
QMessageBox.No)
if reply == QMessageBox.Yes:
event.accept()
else:
event.ignore()
def main():
app = QApplication(sys.argv)
#ex = Example()
menubar = menubarex()
menubar.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
关于python - update()后如何保存以前的矩形?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49283580/