#シンプルなウィンドウ
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import *
def main():
app = QApplication(sys.argv)
w = QWidget()
w.resize(250, 150)
w.setWindowTitle('Window01')
w.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
これが全ての始まりです。
#ウィンドウのリサイズを許さない
import sys
import time
from PyQt5.QtWidgets import *
class SampleWindow(QWidget):
def __init__(self):
QWidget.__init__(self)
self.setWindowTitle("Sample Window")
self.setGeometry(300, 300, 200, 150)
self.setMinimumHeight(100)
self.setMinimumWidth(250)
self.setMaximumHeight(100)
self.setMaximumWidth(250)
if __name__ == '__main__':
myApp = QApplication(sys.argv)
myWindow = SampleWindow()
myWindow.show()
myApp.exec_()
sys.exit(0)
MinimumとMaximumに同じ値を設定することで、リサイズを抑止します。
#ボタンでイベント発生
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication
class Button01(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
btn1 = QPushButton("Button01", self)
btn1.clicked.connect(self.button01Clicked)
self.statusBar()
self.setWindowTitle('Button01')
self.show()
def button01Clicked(self):
sender = self.sender()
self.statusBar().showMessage(sender.text() + ' Push Button01')
if __name__ == '__main__':
app = QApplication(sys.argv)
win = Button01()
sys.exit(app.exec_())
senderメソッドはQWidgetクラスに入っているのでほとんどのウィジットで利用できます。
senderメソッドを使用することで、直前にシグナルを送ってきたウィジットを返してくれます。
帰ってくるのは、ウィジットのインスタンスになります。
何個でも設定できるようです。
複数のボタンがある場合など、どのボタンが押されたのか判定するときなど有効です。
#Color Dialogで色を変える
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.Qt import *
class ColorDialog(QWidget):
def __init__(self):
super(ColorDialog, self).__init__(parent=None)
thisColor = QColor(0, 0, 0)
self.ColorButton = QPushButton('Select Color', self)
self.ColorButton.move(27, 15)
#Qpainterを使う方法もあるが、ここではbackground-colorを設定することで色を変えてみる
self.myFrame = QFrame(self)
self.myFrame.setStyleSheet("QWidget { background-color: %s }" % thisColor.name())
self.myFrame.setGeometry(75, 50, 25, 25)
self.ColorButton.clicked.connect(self.showDialog)
self.setGeometry(200, 100, 175, 100)
self.setWindowTitle('Color Dialog')
self.show()
def showDialog(self):
#ダイアログを表示する
getcolor = QColorDialog.getColor()
if getcolor.isValid():
self.myFrame.setStyleSheet("QWidget { background-color: %s }" % getcolor.name())
if __name__ =='__main__':
App = QApplication(sys.argv)
dialog = ColorDialog()
dialog.show()
App.exec_()
sys.exit()
#Signals and Slots
PyQt4とPyQt5ではSignalとSlotのコーディングスタイルが全くというほど異なります。
以下のページはpysideのコンテンツですが、脳内変換すればPyQt5でも全く問題なく利用できます。
https://wiki.qt.io/Signals_and_Slots_in_PySide/ja
自分で作成したSignal、Slotを利用する場合、大変役に立つはずです。
#カスタムシグナルサンプル
import sys
from PyQt5.QtCore import *
class CustomSignal(QObject):
mySignal = pyqtSignal(str)
def printstr(text):
print(text)
if __name__ == '__main__':
myObject = CustomSignal()
myObject.mySignal.connect(printstr)
myObject.mySignal.emit("カスタムシグナル!")
PyScripterでの実行例です。
#イベントサンプル
import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class EventTest01(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
WiNum = QLCDNumber(self)
Stool = QSlider(Qt.Horizontal, self)
BoxLay = QVBoxLayout()
BoxLay.addWidget(WiNum)
BoxLay.addWidget(Stool)
self.setLayout(BoxLay)
Stool.valueChanged.connect(WiNum.display)
self.setGeometry(500, 500, 300, 200)
self.setWindowTitle('EventTest')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
win = EventTest01()
sys.exit(app.exec_())
#イベントサンプルその2
フレームの上でマウスボタンをクリックするとコンソールにボタンの位置をプリントします。
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.Qt import *
class Test(QWidget):
def __init__(self,parent=None):
super(Test, self).__init__(parent)
self.label = QLabel(self)
self.label.setText('テストボックス')
#http://doc.qt.io/qt-5/qt.html
#上記のページに他の設定もあります
self.label.setAlignment(Qt.AlignCenter)
#http://doc.qt.io/qt-5/qframe.html
#上記のページに他の設定もあります
self.label.setFrameStyle(QFrame.Panel | QFrame.Raised)
self.label.setLineWidth(2)
#マウストラッキングが有効になっている場合、ウィジェットはボタンを押さない場合でも、マウス移動イベントを受け取ります。
self.label.setMouseTracking(True)
self.label.installEventFilter(self)
layout = QVBoxLayout(self)
layout.addWidget(self.label)
def eventFilter(self, object, event):
if event.type() == QEvent.MouseButtonPress and object is self.label:
pos = event.pos()
print('MouseButtonPress: (%d, %d)' % (pos.x(), pos.y()))
return QWidget.eventFilter(self, object, event)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = Test()
window.show()
window.resize(300, 150)
sys.exit(app.exec_())
#PyQt4とPyQt5のコーディングスタイルの違い
PyQt4とpython2.Xで動いていたものが、PyQt5とpython3.Xでは動かないことが
よくあります。
これなどもその例で、
PyQt4:python2.X
settings.value("/myboolsetting", True).toBool()
settings.value("/myintsetting", 10).toInt()[0]
settings.value("/myintsetting").toByteArray()
PyQt5:python3.X
settings.value("/myboolsetting", True, type=bool)
settings.value("/myintsetting", 10, type=int)
settings.value("/myintsetting", QByteArray(), type=QByteArray)
上記のようにコーディングする必要があるそうだ。
これは、"toXXXX"系のメソッドが削除されていることが原因のようだ。
QStringのメソッドは軒並み使えない、そもそもPyQt5にはQStringは存在しない。
PyQt4:python2.X
if mystr.isEmpty()
mystr = QStringList()
myval = QVariant(5)
myval = QVariant("Good Morning")
PyQt5:python3.X
if not mystr
mystr = []
myval = 5
myval = "Good Morning"
他にもあるようだけれども、今後見つけたら追加したい。
#QByteArrayを返すQt5のクラスを使用するとPython3で動かない場合がある
PyQt5のexamplesにscribble.pyがあります、これは2.xでは動くのですが、3.xでは保存時のformat部分でエラーが出てしまう。
この場合、以下の部分を
def createActions(self):
self.openAct = QAction("&Open...", self, shortcut="Ctrl+O",
triggered=self.open)
for format in QImageWriter.supportedImageFormats():
format = str(format)
text = format.upper() + "..."
こうすることで動きます。
def createActions(self):
self.openAct = QAction("&Open...", self, shortcut="Ctrl+O",
triggered=self.open)
for format in QImageWriter.supportedImageFormats():
aaaaa = bytes(format)
#format = str(format)
format = aaaaa.decode('utf-8')
text = format.upper() + "..."
2.xの時はstrでキャストするだけで動いたようですが、3.xではdecodeしてあげないと上手くいきません。
一応コードは掲載しておきます。
ただ、これはあくまでもPyQt5のexamplesのコードです。
from PyQt5.QtCore import QDir, QPoint, QRect, QSize, Qt
from PyQt5.QtGui import QImage, QImageWriter, QPainter, QPen, qRgb
from PyQt5.QtWidgets import (QAction, QApplication, QColorDialog, QFileDialog,
QInputDialog, QMainWindow, QMenu, QMessageBox, QWidget)
from PyQt5.QtPrintSupport import QPrintDialog, QPrinter
class ScribbleArea(QWidget):
def __init__(self, parent=None):
super(ScribbleArea, self).__init__(parent)
self.setAttribute(Qt.WA_StaticContents)
self.modified = False
self.scribbling = False
self.myPenWidth = 1
self.myPenColor = Qt.blue
self.image = QImage()
self.lastPoint = QPoint()
def openImage(self, fileName):
loadedImage = QImage()
if not loadedImage.load(fileName):
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 setPenColor(self, newColor):
self.myPenColor = newColor
def setPenWidth(self, newWidth):
self.myPenWidth = newWidth
def clearImage(self):
self.image.fill(qRgb(255, 255, 255))
self.modified = True
self.update()
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.lastPoint = event.pos()
self.scribbling = True
def mouseMoveEvent(self, event):
if (event.buttons() & Qt.LeftButton) and self.scribbling:
self.drawLineTo(event.pos())
def mouseReleaseEvent(self, event):
if event.button() == Qt.LeftButton and self.scribbling:
self.drawLineTo(event.pos())
self.scribbling = False
def paintEvent(self, event):
painter = 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.image.width())
newHeight = max(self.height() + 128, self.image.height())
self.resizeImage(self.image, QSize(newWidth, newHeight))
self.update()
super(ScribbleArea, self).resizeEvent(event)
def drawLineTo(self, endPoint):
painter = QPainter(self.image)
painter.setPen(QPen(self.myPenColor, self.myPenWidth, Qt.SolidLine,
Qt.RoundCap, Qt.RoundJoin))
painter.drawLine(self.lastPoint, endPoint)
self.modified = True
rad = self.myPenWidth / 2 + 2
self.update(QRect(self.lastPoint, endPoint).normalized().adjusted(-rad, -rad, +rad, +rad))
self.lastPoint = QPoint(endPoint)
def resizeImage(self, image, newSize):
if image.size() == newSize:
return
newImage = QImage(newSize, QImage.Format_RGB32)
newImage.fill(qRgb(255, 255, 255))
painter = QPainter(newImage)
painter.drawImage(QPoint(0, 0), image)
self.image = newImage
def print_(self):
printer = QPrinter(QPrinter.HighResolution)
printDialog = QPrintDialog(printer, self)
if printDialog.exec_() == QPrintDialog.Accepted:
painter = QPainter(printer)
rect = painter.viewport()
size = self.image.size()
size.scale(rect.size(), Qt.KeepAspectRatio)
painter.setViewport(rect.x(), rect.y(), size.width(), size.height())
painter.setWindow(self.image.rect())
painter.drawImage(0, 0, self.image)
painter.end()
def isModified(self):
return self.modified
def penColor(self):
return self.myPenColor
def penWidth(self):
return self.myPenWidth
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.saveAsActs = []
self.scribbleArea = ScribbleArea()
self.setCentralWidget(self.scribbleArea)
self.createActions()
self.createMenus()
self.setWindowTitle("Scribble")
self.resize(500, 500)
def closeEvent(self, event):
if self.maybeSave():
event.accept()
else:
event.ignore()
def open(self):
if self.maybeSave():
fileName, _ = QFileDialog.getOpenFileName(self, "Open File",
QDir.currentPath())
if fileName:
self.scribbleArea.openImage(fileName)
def save(self):
action = self.sender()
fileFormat = action.data()
self.saveFile(fileFormat)
def penColor(self):
newColor = QColorDialog.getColor(self.scribbleArea.penColor())
if newColor.isValid():
self.scribbleArea.setPenColor(newColor)
def penWidth(self):
newWidth, ok = QInputDialog.getInt(self, "Scribble",
"Select pen width:", self.scribbleArea.penWidth(), 1, 50, 1)
if ok:
self.scribbleArea.setPenWidth(newWidth)
def about(self):
QMessageBox.about(self, "About Scribble",
"<p>The <b>Scribble</b> example shows how to use "
"QMainWindow as the base widget for an application, and how "
"to reimplement some of QWidget's event handlers to receive "
"the events generated for the application's widgets:</p>"
"<p> We reimplement the mouse event handlers to facilitate "
"drawing, the paint event handler to update the application "
"and the resize event handler to optimize the application's "
"appearance. In addition we reimplement the close event "
"handler to intercept the close events before terminating "
"the application.</p>"
"<p> The example also demonstrates how to use QPainter to "
"draw an image in real time, as well as to repaint "
"widgets.</p>")
def createActions(self):
self.openAct = QAction("&Open...", self, shortcut="Ctrl+O",
triggered=self.open)
for format in QImageWriter.supportedImageFormats():
aaaaa = bytes(format)
#format = str(format)
format = aaaaa.decode('utf-8')
print("format: %s" % format)
text = format.upper() + "..."
action = QAction(text, self, triggered=self.save)
action.setData(format)
self.saveAsActs.append(action)
self.printAct = QAction("&Print...", self,
triggered=self.scribbleArea.print_)
self.exitAct = QAction("E&xit", self, shortcut="Ctrl+Q",
triggered=self.close)
self.penColorAct = QAction("&Pen Color...", self,
triggered=self.penColor)
self.penWidthAct = QAction("Pen &Width...", self,
triggered=self.penWidth)
self.clearScreenAct = QAction("&Clear Screen", self, shortcut="Ctrl+L",
triggered=self.scribbleArea.clearImage)
self.aboutAct = QAction("&About", self, triggered=self.about)
self.aboutQtAct = QAction("About &Qt", self,
triggered=QApplication.instance().aboutQt)
def createMenus(self):
self.saveAsMenu = QMenu("&Save As", self)
for action in self.saveAsActs:
self.saveAsMenu.addAction(action)
fileMenu = QMenu("&File", self)
fileMenu.addAction(self.openAct)
fileMenu.addMenu(self.saveAsMenu)
fileMenu.addAction(self.printAct)
fileMenu.addSeparator()
fileMenu.addAction(self.exitAct)
optionMenu = QMenu("&Options", self)
optionMenu.addAction(self.penColorAct)
optionMenu.addAction(self.penWidthAct)
optionMenu.addSeparator()
optionMenu.addAction(self.clearScreenAct)
helpMenu = QMenu("&Help", self)
helpMenu.addAction(self.aboutAct)
helpMenu.addAction(self.aboutQtAct)
self.menuBar().addMenu(fileMenu)
self.menuBar().addMenu(optionMenu)
self.menuBar().addMenu(helpMenu)
def maybeSave(self):
if self.scribbleArea.isModified():
ret = QMessageBox.warning(self, "Scribble",
"The image has been modified.\n"
"Do you want to save your changes?",
QMessageBox.Save | QMessageBox.Discard |
QMessageBox.Cancel)
if ret == QMessageBox.Save:
return self.saveFile('png')
elif ret == QMessageBox.Cancel:
return False
return True
def saveFile(self, fileFormat):
print("fileFormat:%s" % fileFormat)
initialPath = QDir.currentPath() + '/untitled.' + fileFormat
fileName, _ = QFileDialog.getSaveFileName(self, "Save As", initialPath,
"%s Files (*.%s);;All Files (*)" % (fileFormat.upper(), fileFormat))
if fileName:
return self.scribbleArea.saveImage(fileName, fileFormat)
return False
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
まあこんな感じです。
これちょと、いじってみようと思っています。
#Macでアプリケーションのアイコンを表示したい
しばらく見ていなかったら、Macでアプリケーションのアイコンが表示されていません。というか、アイコンが出てこない。
うーん、OSのアップグレードが原因かとか調べていると、こんなページを発見
https://stackoverflow.com/questions/35864177/why-using-pyqt5-on-mac-can-not-add-a-icon
import sys
import os
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QIcon
class Example(QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.setGeometry(300,300,300,220)
self.setWindowTitle('Icon')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
path = os.path.join(os.path.dirname(sys.modules[__name__].__file__), 'icon_2.png')
app.setWindowIcon(QIcon(path))
ex = Example()
sys.exit(app.exec_())
#QGraphicsSceneとQGraphicsItemを少々いじってみた
ずっとこの動画が気になっていたんですが、なかなかうまく行かず、何度もも挑戦してました。
QGraphics Basic Example
似たようなことができるようになったんで、YouTubeに動画アップしてみようと思います。
画像的にはこんな感じ、codeは雑です、利用しやすいようにclassでガチガチにはしていません。
これが、正しい使い方なのかも正直わかりません、間違いがあったらどんどんご指摘ください。
ソースは下記に入れますが、以下に承諾された方のみご使用ください。
1.ソースのご利用は利用者の責任において行ってください。個人・法人に限らず利用者は自由に使用することができます。
2.ソースの利用、またはリンク先により生じた損害に対する責任を作者(ケンあずま)は負いません。
3.ソフトを利用した事によるいかなる損害も作者(ケンあずま)は一切の責任を負いません。
4.ソフトは自己の責任の上で使用して下さい。
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'test_Dialog01.ui'
#
# Created by: PyQt5 UI code generator 5.10.1
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog_graphic(object):
def setupUi(self, Dialog_graphic):
Dialog_graphic.setObjectName("Dialog_graphic")
Dialog_graphic.resize(1187, 988)
self.graphicsView = QtWidgets.QGraphicsView(Dialog_graphic)
self.graphicsView.setGeometry(QtCore.QRect(0, 0, 991, 971))
self.graphicsView.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.graphicsView.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.graphicsView.setObjectName("graphicsView")
self.pushButton_rect = QtWidgets.QPushButton(Dialog_graphic)
self.pushButton_rect.setGeometry(QtCore.QRect(1020, 30, 113, 32))
self.pushButton_rect.setObjectName("pushButton_rect")
self.pushButton_rotate = QtWidgets.QPushButton(Dialog_graphic)
self.pushButton_rotate.setGeometry(QtCore.QRect(1020, 210, 113, 32))
self.pushButton_rotate.setObjectName("pushButton_rotate")
self.pushButton_linecolor = QtWidgets.QPushButton(Dialog_graphic)
self.pushButton_linecolor.setGeometry(QtCore.QRect(1020, 500, 112, 34))
self.pushButton_linecolor.setObjectName("pushButton_linecolor")
self.pushButton_fillcolor = QtWidgets.QPushButton(Dialog_graphic)
self.pushButton_fillcolor.setGeometry(QtCore.QRect(1020, 570, 112, 34))
self.pushButton_fillcolor.setObjectName("pushButton_fillcolor")
self.frame_linecolor = QtWidgets.QFrame(Dialog_graphic)
self.frame_linecolor.setGeometry(QtCore.QRect(1060, 530, 41, 21))
self.frame_linecolor.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_linecolor.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_linecolor.setObjectName("frame_linecolor")
self.frame_fillcolor = QtWidgets.QFrame(Dialog_graphic)
self.frame_fillcolor.setGeometry(QtCore.QRect(1060, 600, 41, 21))
self.frame_fillcolor.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_fillcolor.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_fillcolor.setObjectName("frame_fillcolor")
self.layoutWidget = QtWidgets.QWidget(Dialog_graphic)
self.layoutWidget.setGeometry(QtCore.QRect(1030, 420, 111, 28))
self.layoutWidget.setObjectName("layoutWidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.layoutWidget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.label_line = QtWidgets.QLabel(self.layoutWidget)
font = QtGui.QFont()
font.setPointSize(13)
self.label_line.setFont(font)
self.label_line.setObjectName("label_line")
self.horizontalLayout.addWidget(self.label_line)
self.spinBox_line = QtWidgets.QSpinBox(self.layoutWidget)
font = QtGui.QFont()
font.setPointSize(13)
self.spinBox_line.setFont(font)
self.spinBox_line.setLayoutDirection(QtCore.Qt.LeftToRight)
self.spinBox_line.setMinimum(0)
self.spinBox_line.setMaximum(20)
self.spinBox_line.setObjectName("spinBox_line")
self.horizontalLayout.addWidget(self.spinBox_line)
self.Button_elli = QtWidgets.QPushButton(Dialog_graphic)
self.Button_elli.setGeometry(QtCore.QRect(1020, 70, 113, 32))
self.Button_elli.setObjectName("Button_elli")
self.Button_Pory = QtWidgets.QPushButton(Dialog_graphic)
self.Button_Pory.setGeometry(QtCore.QRect(1020, 110, 113, 32))
self.Button_Pory.setObjectName("Button_Pory")
self.layoutWidget1 = QtWidgets.QWidget(Dialog_graphic)
self.layoutWidget1.setGeometry(QtCore.QRect(1030, 370, 111, 26))
self.layoutWidget1.setObjectName("layoutWidget1")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.layoutWidget1)
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.label = QtWidgets.QLabel(self.layoutWidget1)
self.label.setObjectName("label")
self.horizontalLayout_2.addWidget(self.label)
self.spinBox_z = QtWidgets.QSpinBox(self.layoutWidget1)
self.spinBox_z.setMinimum(-10)
self.spinBox_z.setMaximum(10)
self.spinBox_z.setObjectName("spinBox_z")
self.horizontalLayout_2.addWidget(self.spinBox_z)
self.widget = QtWidgets.QWidget(Dialog_graphic)
self.widget.setGeometry(QtCore.QRect(1030, 320, 132, 26))
self.widget.setObjectName("widget")
self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.widget)
self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.label_2 = QtWidgets.QLabel(self.widget)
self.label_2.setObjectName("label_2")
self.horizontalLayout_3.addWidget(self.label_2)
self.doubleSpinBox_scale = QtWidgets.QDoubleSpinBox(self.widget)
self.doubleSpinBox_scale.setDecimals(2)
self.doubleSpinBox_scale.setMinimum(0.1)
self.doubleSpinBox_scale.setMaximum(10.0)
self.doubleSpinBox_scale.setSingleStep(0.1)
self.doubleSpinBox_scale.setProperty("value", 1.0)
self.doubleSpinBox_scale.setObjectName("doubleSpinBox_scale")
self.horizontalLayout_3.addWidget(self.doubleSpinBox_scale)
self.retranslateUi(Dialog_graphic)
QtCore.QMetaObject.connectSlotsByName(Dialog_graphic)
def retranslateUi(self, Dialog_graphic):
_translate = QtCore.QCoreApplication.translate
Dialog_graphic.setWindowTitle(_translate("Dialog_graphic", "Dialog"))
self.pushButton_rect.setText(_translate("Dialog_graphic", "四角形"))
self.pushButton_rotate.setText(_translate("Dialog_graphic", "回転"))
self.pushButton_linecolor.setText(_translate("Dialog_graphic", "線の色"))
self.pushButton_fillcolor.setText(_translate("Dialog_graphic", "面の色"))
self.label_line.setText(_translate("Dialog_graphic", "線幅"))
self.Button_elli.setText(_translate("Dialog_graphic", "円形"))
self.Button_Pory.setText(_translate("Dialog_graphic", "多角形"))
self.label.setText(_translate("Dialog_graphic", "Z深度"))
self.label_2.setText(_translate("Dialog_graphic", "拡大縮小"))
import sys
import os
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from ui_test_Dialog01 import Ui_Dialog_graphic
class Test (QWidget):
def __init__(self, parent=None):
super (Test, self).__init__ (parent)
self.setWindowFlags(
Qt.Window | Qt.CustomizeWindowHint | Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowCloseButtonHint)
self.ui = Ui_Dialog_graphic()
self.ui.setupUi (self)
self.scene = QGraphicsScene()
self.ui.graphicsView.setScene(self.scene)
#線色の初期設定 StyleSheetで
self.line_col = QColor('black')
self.ui.frame_linecolor.setStyleSheet("QWidget { background-color: black }")
#塗り色の初期設定 paletteで
self.fill_col = QColor('white')
pal = self.ui.frame_fillcolor.palette()
pal.setColor(QPalette.Background,Qt.white)
self.ui.frame_fillcolor.setAutoFillBackground(True)
self.ui.frame_fillcolor.setPalette(pal)
#signal & slot
self.ui.pushButton_rect.clicked.connect(self.addBOX)
self.ui.Button_elli.clicked.connect(self.addElli)
self.ui.Button_Pory.clicked.connect(self.addPory)
self.ui.pushButton_rotate.clicked.connect(self.rotate)
self.ui.doubleSpinBox_scale.valueChanged.connect(self.scale)
self.ui.pushButton_linecolor.clicked.connect(self.linecolor)
self.ui.pushButton_fillcolor.clicked.connect(self.fillcolor)
self.ui.spinBox_line.valueChanged.connect(self.setlinewidth)
self.ui.spinBox_z.valueChanged.connect(self.setZvalue)
self.scene.selectionChanged.connect(self.item_selectChanged)
#penの設定
self.pen = QPen(Qt.SolidLine)
self.pen.setColor(Qt.black)
self.linewidth = 5
self.pen.setWidth(self.linewidth)
self.pen.setCapStyle(Qt.FlatCap)
self.pen.setJoinStyle(Qt.MiterJoin)
#QGraphicsItemの初期化
self.rect = None
self.ellipse = None
self.polygon = None
def item_selectChanged(self):
self.ui.doubleSpinBox_scale.setValue(1.0)
width = self.linewidth
self.ui.spinBox_line.setValue(width)
self.pen.setWidth(self.linewidth)
item = self.selectedItem()
if item:
item.setBrush(self.fill_col)
item.setPen(self.pen)
def setZvalue(self):
for item in self.scene.items():
if item.isSelected() == True:
item.setZValue(self.ui.spinBox_z.value())
else:
pass
def linecolor(self):
col = QColorDialog.getColor()
if col.isValid():
self.line_col = col
self.ui.frame_linecolor.setStyleSheet("QWidget { background-color: %s }" % self.line_col.name())
item = self.selectedItem()
if item:
self.pen.setColor(self.line_col)
item.setPen(self.pen)
def fillcolor(self):
col = QColorDialog.getColor()
if self.fill_col.isValid():
self.fill_col = col
self.ui.frame_fillcolor.setStyleSheet("QWidget { background-color: %s }" % self.fill_col.name())
item = self.selectedItem()
if item:
item.setBrush(self.fill_col)
def setlinewidth(self):
self.linewidth = self.ui.spinBox_line.value()
self.pen.setColor(self.line_col)
self.pen.setWidth(self.linewidth)
item = self.selectedItem()
if item:
item.setBrush(self.fill_col)
item.setPen(self.pen)
self.linewidth = self.ui.spinBox_line.value()
self.pen.setWidth(self.linewidth)
item.setPen(self.pen)
def addBOX(self):
self.rect = QGraphicsRectItem(0, 0, 240, 240)
self.scene.addItem(self.rect)
self.rect.setFlag(QGraphicsItem.ItemIsSelectable)
self.rect.setFlag(QGraphicsItem.ItemIsMovable)
self.rect.setFlag(QGraphicsItem.ItemIsFocusable)
self.pen.setColor(self.line_col)
self.rect.setBrush(self.fill_col)
self.rect.setPen(self.pen)
def addElli(self):
self.ellipse = QGraphicsEllipseItem(0,0,240,240)
self.scene.addItem(self.ellipse)
self.ellipse.setFlag(QGraphicsItem.ItemIsSelectable)
self.ellipse.setFlag(QGraphicsItem.ItemIsMovable)
self.ellipse.setFlag(QGraphicsItem.ItemIsFocusable)
self.pen.setColor(self.line_col)
self.ellipse.setBrush(self.fill_col)
self.ellipse.setPen(self.pen)
def addPory(self):
mypoly = QPolygonF([
QPointF(80, 0), # 1
QPointF(160, 0), # 2
QPointF(160, 80), # 3
QPointF(240, 80), # 4
QPointF(240, 160), # 5
QPointF(160, 160), # 6
QPointF(160, 240), # 7
QPointF(80, 240), # 8
QPointF(80, 160), # 9
QPointF(0, 160), # 10
QPointF(0, 80), # 11
QPointF(80, 80) # 12
])
self.polygon = QGraphicsPolygonItem(mypoly)
self.scene.addItem(self.polygon)
self.polygon.setFlag(QGraphicsItem.ItemIsSelectable)
self.polygon.setFlag(QGraphicsItem.ItemIsMovable)
self.polygon.setFlag(QGraphicsItem.ItemIsFocusable)
self.pen.setColor(self.line_col)
self.polygon.setBrush(self.fill_col)
self.polygon.setPen(self.pen)
def rotate(self):
item = self.selectedItem()
if item:
centerX = item.boundingRect().width() / 2
centerY = item.boundingRect().height() / 2
item.setTransformOriginPoint(centerX , centerY)
item.setRotation(item.rotation() + 30)
def scale(self):
rate = self.ui.doubleSpinBox_scale.value()
if rate <= 0.0:
return
item = self.selectedItem()
if item:
centerX = item.boundingRect().width() / 2
centerY = item.boundingRect().height() / 2
item.setTransformOriginPoint(centerX, centerY)
item.setScale(rate)
self.linewidth = self.ui.spinBox_line.value()
self.pen.setWidth(self.linewidth)
item.setBrush(self.fill_col)
item.setPen(self.pen)
def selectedItem(self):
items = self.scene.selectedItems()
if len(items) == 1:
return items[0]
return None
if __name__ == '__main__':
app = QApplication (sys.argv)
path = os.path.join(os.path.dirname(sys.modules[__name__].__file__), 'icon_2.png')
app.setWindowIcon(QIcon(path))
window = Test ()
window.show ()
sys.exit (app.exec_ ())
いろんなことができるんでしょうが、2Dは難しいです。
ソースについて少々解説します。
setWindowFlagsはWindowをDialog風にしたりと手動でWindowのスタイルを決めることのできるメソッドです。
別に、Qt Designerで画面作っているなら設定する必要がないように思いますが、Macの最新版のOSの場合、普通に画面を作ると以下のように余計なものがついてきます。
タイトルバーの下にタイトルバーみたいなものが、これはっきり言って邪魔です。setWindowFlagsを設定することでこれは消えます。
selectedItemはselectedItemsで選択されているitemの先頭を返します。
ソースでは、複数選択を許していないので、選択されているitemそのものが返却されます。
回転も拡大も以下のコードで選択itemの中心座標を取得します。
centerX = item.boundingRect().width() / 2
centerY = item.boundingRect().height() / 2
setTransformOriginPointによってitem座標に変換の原点を設定します