我是PYQT5的新手,我尝试用C++编写一些代码,将其用Qt翻译成PYQT5: 这是一个绘图应用程序,如图所示:http://www.newthinktank.com/2018/07/qt-tutorial-5-paint-app/
import PyQt5
from PyQt5 import QtWidgets
from PyQt5 import QtGui, QtCore
import sys
class ScribbleArea(QtWidgets.QWidget):
def __init__(self, parent = 0):
super().__init__()
self.parent = parent
self.modified = False
self.scribbling = False
self.myPenColor = QtCore.Qt.blue
self.myPenWidth = 1
self.image = None
self.lastPoint = None
self.setAttribute(QtCore.Qt.WA_StaticContents)
def openImage(self, fileName):
loadedImage = QtGui.QImage(fileName)
if not loadedImage:
return False
newSize = loadedImage.size().expandedTo(self.size())
self.resizeImage(loadedImage, newSize)
self.image = loadedImage
self.modified = False
self.update()
return True
def saveImage(self, fileName, fileFormat):
visibleImage = self.image
self.resizeImage(visibleImage, self.size())
if visibleImage.save(fileName, fileFormat):
self.modified = False
return True
else:
return False
def clearImage(self):
self.image.fill(QtGui.QColor(255, 255, 255))
self.modified = True
self.update()
def print(self):
try:
from PyQt5.QtPrintSupport import QPrinter, QPrintDialog
except ImportError as e:
print("not print support")
else:
printer = QPrinter(QPrinter.HighResolution)
printDialog = QPrintDialog(printer, self)
if printDialog.exec_() == QtWidgets.QDialog.Accepted:
painter = QtGui.QPainter(printer)
rect = painter.viewport()
size = self.image.size()
size.scale(rect.size(), QtCore.Qt.KeepAspectRatio)
painter.setViewport(rect.x(), rect.y(), size.width(), size.height())
painter.setWindow(self.image.rect())
painter.drawImage(0, 0, self.image)
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
self.lastPoint = event.pos()
self.scribbling = True
def mouseMoveEvent(self, event):
if (event.buttons() & QtCore.Qt.LeftButton) and self.scribbling:
self.drawLineTo(event.pos())
def mouseReleaseEvent(self, event):
if event.button() == QtCore.Qt.LeftButton and self.scribbling:
self.drawLineTo(event.pos())
self.scribbling = False
def paintEvent(self, event):
painter = QtGui.QPainter(self)
dirtyRect = event.rect()
painter.drawImage(dirtyRect, self.image, dirtyRect)
def resizeEvent(self, event):
if self.width() > self.image.width() or self.height() > self.image.height():
newWidth = max(self.width() + 128, self.width())
newHeight = max(self.height() + 128, self.height())
self.resizeImage(self.image, QtCore.QSize(newWidth, newHeight))
self.update()
QtWidgets.QWidget.resizeEvent(self, event)
def drawLineTo(self, endPoint):
painter = QtGui.QPainter(self.image)
painter.setPen(QtGui.QPen(self.myPenColor, self.myPenWidth, QtCore.Qt.SolidLine,
QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
painter.drawLine(self.lastPoint, endPoint)
self.modified = True
rad = (self.myPenWidth / 2) + 2
self.update(QtCore.QRect(self.lastPoint, endPoint).normalize().adjusted(-rad, -rad, +rad, +rad))
self.lastPoint = endPoint
def resizeImage(self, image, newSize):
if image.size() == newSize:
return
newImage = QtGui.QImage(newSize, QtGui.QImage.Format_RGB32)
newImage.fill(QtGui.QColor(255, 255, 255))
painter = QtGui.QPainter(newImage)
painter.drawImage(QtCore.QPoint(0, 0), image)
image = newImage #
return image #
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.scribbleArea = ScribbleArea()
self.saveAsMenu = None
self.fileMenu = None
self.optionMenu = None
self.helpMenu = None
self.openAct = None
self.saveAsActs = []
self.penColorAct = None
self.penWidthAct = None
self.printAct = None
self.exitAct = None
self.clearScreenAct = None
self.aboutAct = None
self.aboutQtAct = None
self.setCentralWidget(self.scribbleArea)
self.createActions()
self.createMenus()
self.setWindowTitle(self.tr("Scribble"))
self.resize(500, 500)
self.createMenus()
self.createActions()
def closeEvent(self, event):
if self.maybeSave():
event.accept()
else:
event.ignore()
def open(self):
if self.maybeSave():
fileName,_filter = QtWidgets.QFileDialog.getOpenFileName(self, self.tr("Open File"), QtCore.QDir.currentPath())
if fileName:
self.scribbleArea.openImage(fileName)
def save(self):
action = QtWidgets.QAction(self.sender()) #action = self.sender()
fileFormat = action.data().toByteArray()
self.saveFile(fileFormat)
def close(self):
pass
def penColor(self):
newColor = QtWidgets.QColorDialog.getColor(self.scribbleArea.myPenColor) #.penColor()
if newColor.isValid():
self.scribbleArea.myPenColor = newColor
def penWidth(self):
newWidth, ok = QtWidgets.QInputDialog.getInt(self, self.tr("Scribble"), self.tr("Select pen width: "),
self.scribbleArea.myPenWidth, 1, 50, 1)
if ok:
self.scribbleArea.myPenWidth = newWidth
def about(self):
QtWidgets.QMessageBox.about(self, self.tr("About scribble"), self.tr("<p>The <b>Scribble</b> example is awesome</p>"))
def createActions(self):
self.openAct = QtWidgets.QAction(self.tr("Open"), self)
self.openAct.setShortcuts(QtGui.QKeySequence.Open)
self.openAct.triggered.connect(self.open)
for format in QtGui.QImageWriter.supportedImageFormats():
text = self.tr("{}...").format(str(format).upper())
action = QtWidgets.QAction(text, self)
action.setData(format)
action.triggered.connect(self.save)
self.saveAsActs.append(action)
self.printAct = QtWidgets.QAction(self.tr("Print"), self)
self.printAct.triggered.connect(self.scribbleArea.print) #
self.exitAct = QtWidgets.QAction(self.tr("Exit"), self)
self.exitAct.setShortcuts(QtGui.QKeySequence.Quit)
self.exitAct.triggered.connect(self.close)
self.penColorAct = QtWidgets.QAction(self.tr("Pen color..."), self)
self.penColorAct.triggered.connect(self.penColor)
self.penWidthAct = QtWidgets.QAction(self.tr("Pen width..."), self)
self.penWidthAct.triggered.connect(self.penWidth)
self.clearScreenAct = QtWidgets.QAction(self.tr("Clear Screen..."), self)
self.clearScreenAct.setShortcut(self.tr("Ctrl+L"))
self.clearScreenAct.triggered.connect(self.scribbleArea.clearImage) #
self.aboutAct = QtWidgets.QAction(self.tr("About..."), self)
self.aboutAct.triggered.connect(self.about)
self.aboutQtAct = QtWidgets.QAction(self.tr("About Qt ..."), self)
self.aboutQtAct.triggered.connect(QtWidgets.qApp.aboutQt)
def createMenus(self):
self.saveAsMenu = QtWidgets.QMenu(self.tr("Save as"), self)
for action in self.saveAsActs:
self.saveAsMenu.addAction(action)
self.fileMenu = QtWidgets.QMenu(self.tr("File"), self)
self.fileMenu.addAction(self.openAct)
self.fileMenu.addMenu(self.saveAsMenu)
self.fileMenu.addAction(self.printAct)
self.fileMenu.addSeparator()
self.fileMenu.addAction(self.exitAct)
self.optionMenu = QtWidgets.QMenu(self.tr("Options"), self)
self.optionMenu.addAction(self.penColorAct)
self.optionMenu.addAction(self.penWidthAct)
self.optionMenu.addSeparator()
self.optionMenu.addAction(self.clearScreenAct)
self.helpMenu = QtWidgets.QMenu(self.tr("Help"), self)
self.helpMenu.addAction(self.aboutAct)
self.helpMenu.addAction(self.aboutQtAct)
self.menuBar().addMenu(self.fileMenu)
self.menuBar().addMenu(self.optionMenu)
self.menuBar().addMenu(self.helpMenu)
def maybeSave(self):
if self.scribbleArea.modified:
ret = QtWidgets.QMessageBox.warning(self, self.tr("Scribble"), self.tr("The image has been modified. \n"
"Do you want to save the changes?"),
QtWidgets.QMessageBox.Save | QtWidgets.QMessageBox.Discard | QtWidgets.QMessageBox.Cancel)
if ret == QtWidgets.QMessageBox.Save:
return self.saveFile("png")
elif ret == QtWidgets.QMessageBox.Cancel:
return False
return True
def saveFile(self, fileFormat):
initialPath = QtCore.QDir.currentPath() + "/untitled." + fileFormat
fileName = QtWidgets.QFileDialog.getSaveFileName(
self,
self.tr("Save As"),
initialPath,
self.tr("{} Files (*.{});;All Files (*)").format(fileFormat.upper(), fileFormat))
if not fileName:
return False
else:
return self.scribbleArea.saveImage(fileName, fileFormat.constData())
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
我尝试过调试,但很明显它在“window.show()”时崩溃了。正如我所说,我是新来的,我不擅长自己调试它
如果在提示符/终端中运行程序,您将清楚地看到以下回溯:
这是因为
self.image
仍然是None
,并且None
没有属性必须在代码中添加检查,以确保已设置属性:
注意}
drawLineTo()
函数中还有一个语法错误,正如您使用的normalize()
,但它实际上是^{相关问题 更多 >
编程相关推荐