Commit d6af372b authored by Josef Brandt's avatar Josef Brandt

Merge branch 'Thresholding,Background' into RefactoringAnalysisModules

parents 92f24fb4 48537f7f
......@@ -42,7 +42,13 @@ class ParticleContainer(object):
self.measurements.append(Measurement())
indexOfNewMeas = len(self.measurements)-1
return indexOfNewMeas
def clearParticles(self):
self.particles = []
def clearMeasurements(self):
self.measurements = []
def setMeasurementScanIndex(self, indexOfMeasurment, scanIndex):
self.measurements[indexOfMeasurment].ramanScanIndex = scanIndex
......
......@@ -149,6 +149,7 @@ class DataSet(object):
# self.particlestats = []
# self.ramanscansortindex = None
self.particleContainer = ParticleContainer(self)
self.particleDetectionDone = False
self.ramanscandone = False
# self.results = {'polymers': None,
......@@ -246,40 +247,30 @@ class DataSet(object):
self.imagedim_bf = self.imagedim
self.imagedim_df = self.imagedim
del self.imagedim
if not hasattr(self, 'particles2spectra'):
self.particles2spectra = [[int(np.where(self.ramanscansortindex == i)[0])] for i in range(len(self.ramanscansortindex))]
self.version = 2
if self.version == 2:
self.particleContainer = ParticleContainer(self)
def recreateMeasurement2ParticleFromScanIndices():
measurements2particles = [[int(np.where(self.ramanscansortindex == i)[0])] for i in range(len(self.ramanscansortindex))]
return measurements2particles
self.particleContainer.initializeParticles(len(self.particlestats))
self.particleContainer.setParticleContours(self.particlecontours)
self.particleContainer.setParticleStats(self.particlestats)
self.particleContainer.applyPixelScaleToParticleStats(self.getPixelScale())
if hasattr(self, 'particles2spectra'):
if self.particles2spectra is not None:
measurements2particles = self.particles2spectra
else:
measurements2particles = recreateMeasurement2ParticleFromScanIndices()
else:
measurements2particles = recreateMeasurement2ParticleFromScanIndices()
for particleIndex, listOfScanIndices in enumerate(measurements2particles):
curParticle = self.particleContainer.getParticleOfIndex(particleIndex)
for scanIndex in listOfScanIndices:
# curParticle.addEmptyMeasurement()
# curParticle.setMeasurementPixelCoords(measIndex, x, y)
# curParticle.setMeasurementScanIndex(measIndex, scanIndex)
indexOfNewMeas = self.particleContainer.addEmptyMeasurement()
x, y = self.ramanpoints[particleIndex][0], self.ramanpoints[particleIndex][1]
self.particleContainer.setMeasurementPixelCoords(indexOfNewMeas, x, y)
self.particleContainer.setMeasurementScanIndex(indexOfNewMeas, scanIndex)
curParticle.addMeasurement(self.particleContainer.measurements[indexOfNewMeas])
if len(self.particlestats) > 0: #i.e., particle detection was completed and particle data is there
for particleIndex, listOfScanIndices in enumerate(self.particles2spectra):
curParticle = self.particleContainer.getParticleOfIndex(particleIndex)
for scanIndex in listOfScanIndices:
indexOfNewMeas = self.particleContainer.addEmptyMeasurement()
x, y = self.ramanpoints[particleIndex][0], self.ramanpoints[particleIndex][1]
self.particleContainer.setMeasurementPixelCoords(indexOfNewMeas, x, y)
self.particleContainer.setMeasurementScanIndex(indexOfNewMeas, scanIndex)
curParticle.addMeasurement(self.particleContainer.measurements[indexOfNewMeas])
for particle in self.particleContainer.particles:
for meas in particle.measurements:
......@@ -292,8 +283,6 @@ class DataSet(object):
# self.version = 3
# add later conversion for higher version numbers here
def getSubImage(self, img, index, draw=True):
contour = self.particlecontours[index]
x0, x1 = contour[:,0,0].min(), contour[:,0,0].max()
......@@ -395,28 +384,14 @@ class DataSet(object):
def getLegacyDetectImageName(self):
return os.path.join(self.path, "detectimage.png")
def getBackgroundImageName(self):
return os.path.join(self.path, "background.bmp")
def getDetectImageName(self):
raise NotImplementedError("No longer implemented due to change in API")
def getTmpImageName(self):
return os.path.join(self.path, "tmp.bmp")
def saveParticleData(self):
print('Not saving ParticleData into text file...:\nThe current output format might be wrong, if multiple spectra per particle are present...')
# if len(self.ramanscansortindex)>0:
# data = []
# pixelscale = (self.pixelscale_df if self.imagescanMode == 'df' else self.pixelscale_bf)
# for i in self.ramanscansortindex:
# data.append(list(self.ramanpoints[i])+list(self.particlestats[i]))
# data = np.array(data)
# data[:,0], data[:,1], z = self.mapToLengthRaman((data[:,0], data[:,1]), microscopeMode=self.imagescanMode, noz=True)
# data[:,2:7] *= pixelscale
# header = "x [µm], y [µm], length [µm], height [µm], length_ellipse [µm], height_ellipse [µm]"
# if data.shape[1]>6:
# header = header + ", area [µm^2]"
# data[:,6] *= pixelscale
# np.savetxt(os.path.join(self.path, "particledata.txt"), data,
# header=header)
def save(self):
saveData(self, self.fname)
......
......@@ -20,7 +20,7 @@ If not, see <https://www.gnu.org/licenses/>.
"""
import numpy as np
from PyQt5 import QtCore, QtWidgets, QtGui
from segmentation import Segmentation
from segmentation import Segmentation, MeasurementPoint
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
import matplotlib.pyplot as plt
from threading import Thread
......@@ -248,7 +248,9 @@ class ImageView(QtWidgets.QLabel):
painter.setPen(QtCore.Qt.red)
painter.setBrush(QtCore.Qt.red)
for p in self.measpoints:
painter.drawEllipse(p[0]-2, p[1]-2, 5, 5)
for point in self.measpoints[p]:
# painter.drawEllipse(p[0]-2, p[1]-2, 5, 5)
painter.drawEllipse(point.x-2, point.y-2, 5, 5)
if self.showseedpoints:
painter.setPen(QtCore.Qt.white)
......@@ -581,10 +583,9 @@ class ParticleDetectionView(QtWidgets.QWidget):
@QtCore.pyqtSlot()
def clearDetection(self):
if self.dataset is not None:
self.dataset.ramanpoints = []
self.dataset.particlecontours = []
self.dataset.particlestats = []
self.dataset.ramanscansortindex = []
self.dataset.particleContainer.clearParticles()
self.dataset.particleContainer.clearMeasurements()
self.dataset.particleDetectionDone = False
self.dataset.ramanscandone = False
self.dataset.mode = "opticalscan"
self.dataset.save()
......@@ -676,7 +677,7 @@ class ParticleDetectionView(QtWidgets.QWidget):
curParticle.addMeasurement(particleContainer.measurements[indexOfNewMeas])
self.dataset.particleDetectionDone = True
# self.dataset.ramanpoints = measurementPoints #consider moving that to particleContainer
# self.dataset.particlecontours = contours
# self.dataset.particlestats = particlestats
......
......@@ -102,12 +102,13 @@ class GEPARDMainWindow(QtWidgets.QMainWindow):
if fileName:
isValid, msg = self.testFilename(fileName)
if isValid:
self.fname = str(fileName) #TODO: No spaces for Renishaw Interface!!
self.fname = str(fileName)
self.view.new(self.fname)
self.scalingChanged(1.)
else:
QtWidgets.QMessageBox.critical(self, "Error", msg)
@QtCore.pyqtSlot()
def testFilename(self, fileName):
if self.view.ramanctrl.name == 'RenishawCOM': #the renishawCom does not allow Spaces within filePath
if fileName.find(' ') == 0:
......@@ -116,7 +117,7 @@ class GEPARDMainWindow(QtWidgets.QMainWindow):
return True, ""
else:
return True, ""
@QtCore.pyqtSlot()
def about(self):
QtWidgets.QMessageBox.about(self, 'GEPARD',
......@@ -202,7 +203,7 @@ class GEPARDMainWindow(QtWidgets.QMainWindow):
self.configRamanCtrlAct.triggered.connect(self.view.configureRamanControl)
if self.view.simulatedRaman:
self.configRamanCtrlAct.setDisabled(True)
def updateModes(self, active=None, maxenabled=None):
ose, osc, pde, pdc, rse, rsc, pae, pac = [False]*8
if maxenabled=="OpticalScan":
......
......@@ -48,15 +48,17 @@ def imageStacking(colimgs):
return im, zval
def combineImages(path, nx, ny, nk, width, height, angle):
imgs = []
full = None
for i in range(nx):
for j in range(ny):
colimgs = []
for k in range(nk):
colimgs.append(cv2.imread(path + f'test_{i}_{j}_{k}.bmp'))
img = imageStacking(colimgs)
imgs.append(img)
if nk > 1:
colimgs = []
for k in range(nk):
colimgs.append(cv2.imread(path + f'test_{i}_{j}_{k}.bmp'))
img = imageStacking(colimgs)
else:
img = cv2.imread(path + f'test_{i}_{j}_1.bmp')
dx = i*.9*img.shape[1]
dy = j*.8*img.shape[0]
c, s = np.cos(np.radians(angle)), np.sin(np.radians(angle))
......@@ -67,6 +69,7 @@ def combineImages(path, nx, ny, nk, width, height, angle):
full = dst
else:
full = cv2.max(full,dst)
cv2.imwrite("full_dunkel.png", full)
......
# -*- coding: utf-8 -*-
"""
GEPARD - Gepard-Enabled PARticle Detection
Copyright (C) 2018 Lars Bittrich and Josef Brandt, Leibniz-Institut für
Polymerforschung Dresden e. V. <bittrich-lars@ipfdd.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program, see COPYING.
If not, see <https://www.gnu.org/licenses/>.
"""
from PyQt5 import QtCore, QtWidgets, QtGui
import cv2
import numpy as np
import os
from helperfunctions import cv2imread_fix
class BackGroundManager(QtWidgets.QWidget):
managerClosed = QtCore.pyqtSignal()
readBackground = QtCore.pyqtSignal(int)
def __init__(self, parentOSwidget):
super(BackGroundManager, self).__init__()
self.setFixedSize(1500, 900)
self.setWindowTitle('Optical Background Manager')
self.parentOSwidget = parentOSwidget
self.parentOSwidget.backGroundSavedToPath.connect(self.updateChildImage)
self.ramanctrl = self.parentOSwidget.ramanctrl
layout = QtWidgets.QHBoxLayout()
self.setLayout(layout)
self.imagesGroup = QtWidgets.QGroupBox('Current Background Images')
self.imagesLayout = QtWidgets.QGridLayout()
self.imgContainers = []
self.avgImg = None
self.presetIndividualImages()
self.previewImage = QtWidgets.QGraphicsView()
self.setupGraphicsView(self.previewImage, scaleFactor=0.8)
previewGroup = QtWidgets.QGroupBox()
previewLayout = QtWidgets.QVBoxLayout()
self.blurspinbox = QtWidgets.QSpinBox(self)
self.blurspinbox.setMinimum(3)
self.blurspinbox.setMaximum(99)
self.blurspinbox.setSingleStep(2)
self.blurspinbox.setValue(5)
self.blurspinbox.valueChanged.connect(self.calculateAverageImage)
self.blurspinbox.setMaximumWidth(150)
self.previewCurrentViewBtn = QtWidgets.QPushButton('Acquire 3x3 area and preview subtracted result')
self.previewCurrentViewBtn.clicked.connect(self.previewStitchedArea)
self.previewArea = QtWidgets.QGraphicsView()
self.setupGraphicsView(self.previewArea, scaleFactor=0.5)
previewLayout.addWidget(QtWidgets.QLabel('Radius for blur'))
previewLayout.addWidget(self.blurspinbox)
previewLayout.addWidget(QtWidgets.QLabel('Preview of averaged and smoothed image'))
previewLayout.addWidget(self.previewImage)
previewLayout.addWidget(self.previewCurrentViewBtn)
previewLayout.addWidget(self.previewArea)
previewGroup.setLayout(previewLayout)
layout.addWidget(self.imagesGroup)
layout.addWidget(previewGroup)
def presetIndividualImages(self, nrows=3, ncols=2):
index = 0
for row in range(nrows):
for col in range(ncols):
self.imgContainers.append(SingleImageContainer(self, index))
self.imagesLayout.addWidget(self.imgContainers[-1], row, col)
index += 1
self.imagesGroup.setLayout(self.imagesLayout)
def previewStitchedArea(self):
if self.avgImg is None:
QtWidgets.QMessageBox.about(self, 'Warning', 'No Background Image is aquired')
return
else:
from opticalscan import loadAndPasteImage
self.dataset = self.parentOSwidget.dataset
#acquire images in 3x3 area to preview quality of background subtraction
x, y, z = self.ramanctrl.getPosition()
micMode = self.parentOSwidget.view.microscopeMode
width, height, angle = self.ramanctrl.getImageDimensions(micMode)
startPoint = [x-width, y-height]
endPoint = [x+width, y+height]
points = np.concatenate(([startPoint], [endPoint]), axis=0)
p0 = [points[:,0].min(), points[:,1].max()]
p1 = [points[:,0].max(), points[:,1].min()]
reply = QtWidgets.QMessageBox.question(self, 'Message',f"The stage will move {round(3*width)} in x and {round(3*height)} in y.\nContinue?",
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes:
fullimg = None
zimg = None
for row in range(3):
for col in range(3):
curPoint = [startPoint[0] + row*width, startPoint[1] + col*height]
self.ramanctrl.moveToAbsolutePosition(curPoint[0], curPoint[1])
self.ramanctrl.saveImage(self.dataset.getTmpImageName())
fullimg, zimg = loadAndPasteImage([self.dataset.getTmpImageName()], fullimg, zimg, width, height, angle, p0, p1, curPoint, background=self.avgImg)
self.updateGraphicsView(self.previewArea, fullimg, convertColors=True)
def setupGraphicsView(self, graphView, scaleFactor=1.):
graphView.item = QtWidgets.QGraphicsPixmapItem()
scene = QtWidgets.QGraphicsScene(graphView)
scene.addItem(graphView.item)
graphView.setScene(scene)
graphView.scale(scaleFactor, scaleFactor)
def updateGraphicsView(self, graphView, img, convertColors=False):
if img is not None:
prevImg = img
else:
prevImg = np.zeros((300, 300))
if convertColors:
prevImg = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
height, width = prevImg.shape[:2]
bytesPerLine = 3 * width
pix = QtGui.QPixmap()
pix.convertFromImage(QtGui.QImage(prevImg, width, height, bytesPerLine, QtGui.QImage.Format_RGB888))
graphView.item.setPixmap(pix)
@QtCore.pyqtSlot(int, str)
def updateChildImage(self, index, path):
self.imgContainers[index].updateImage(path)
self.calculateAverageImage()
def calculateAverageImage(self):
curImgs = [i.getImage() for i in self.imgContainers if i.getImage() is not None]
if len(curImgs) > 0:
curImgs = np.array(curImgs)
self.avgImg = np.sum(curImgs, axis=0)/len(curImgs)
radius = self.blurspinbox.value()
if radius %2 == 0:
radius += 1
if radius < 0:
radius = 1
self.avgImg = cv2.GaussianBlur(self.avgImg, (radius, radius), 0)
self.avgImg = np.uint8(self.avgImg)
self.parentOSwidget.writeBackGroundImage(self.avgImg)
else:
self.avgImg = None
self.parentOSwidget.deleteBackGroundImage()
self.updateGraphicsView(self.previewImage, self.avgImg)
def closeEvent(self, event):
self.managerClosed.emit()
event.accept()
class SingleImageContainer(QtWidgets.QGroupBox):
def __init__(self, parent, index):
super(SingleImageContainer, self).__init__()
self.index = index
self.parent = parent
layout = QtWidgets.QVBoxLayout()
layout.addWidget(QtWidgets.QLabel(f'Background {index+1}'))
readBtn = QtWidgets.QPushButton('ReadImage')
readBtn.clicked.connect(self.readImage)
self.image = ImagePixmap()
delBtn = QtWidgets.QPushButton('Delete Image')
delBtn.clicked.connect(self.clearImage)
layout.addWidget(readBtn)
layout.addWidget(self.image)
layout.addWidget(delBtn)
self.setLayout(layout)
def readImage(self):
self.parent.readBackground.emit(self.index)
def updateImage(self, path):
self.image.updateImage(path)
def clearImage(self):
self.image.clearImage()
self.parent.calculateAverageImage()
def getImage(self):
return self.image.imgdata
class ImagePixmap(QtWidgets.QGraphicsView):
def __init__(self):
super(ImagePixmap, self).__init__()
self.item = QtWidgets.QGraphicsPixmapItem()
self.item.setPos(0, 0)
self.item.setAcceptedMouseButtons(QtCore.Qt.NoButton)
self.imgdata = None
scene = QtWidgets.QGraphicsScene(self)
scene.addItem(self.item)
self.setScene(scene)
self.scale(0.4, 0.4)
self.updateImage()
def updateImage(self, img_path=None):
if img_path is None:
self.loadImageIntoPixmap(self.createBlancImage())
elif os.path.exists(img_path):
self.imgdata = cv2.cvtColor(cv2imread_fix(img_path), cv2.COLOR_BGR2RGB)
self.loadImageIntoPixmap(self.imgdata)
def createBlancImage(self):
blancImg = np.zeros((300, 500, 3))
cv2.putText(blancImg, 'None selected', (150, 150), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255), 2)
return blancImg
def loadImageIntoPixmap(self, img):
height, width = img.shape[:2]
bytesPerLine = 3 * width
pix = QtGui.QPixmap()
pix.convertFromImage(QtGui.QImage(img, width, height, bytesPerLine, QtGui.QImage.Format_RGB888))
self.item.setPixmap(pix)
def clearImage(self):
self.imgdata = None
self.updateImage()
This diff is collapsed.
......@@ -211,9 +211,22 @@ class WITecCOM(RamanBase):
# move only if new position is really different; repeat if new position is ignored (happens some times)
while max(abs(initpos[0]-x), abs(initpos[1]-y))>epsxy:
t0 = time()
self.PosXFloatMan.SetValue(x)
self.PosYFloatMan.SetValue(y)
self.GoToTrigger.OperateTrigger()
numFails = 0
maxFails = 50
positionSubmitted = False
while numFails < maxFails and not positionSubmitted:
try:
self.PosXFloatMan.SetValue(x)
self.PosYFloatMan.SetValue(y)
self.GoToTrigger.OperateTrigger()
positionSubmitted = True
except pythoncom.com_error:
numFails += 1
sleep(.1)
if numFails > 0:
print(f'{numFails} of max. {maxFails} unsuccessfull position submits to Position: {x}, {y}', flush=True)
if not positionSubmitted:
print(f'Error setting Position: {x}, {y}\nExpecting \"signal ignored\" warning', flush=True)
# wait till position is found within accuracy of epsxy; check if position changes at all
distance = 2*epsxy
......@@ -297,7 +310,6 @@ class WITecCOM(RamanBase):
print("Waiting for measurement ready...")
t1 = time()
def triggerMeasurement(self, num):
assert self.timeseries
self.TimeSeriesSlowNextMan.OperateTrigger()
......
......@@ -235,8 +235,6 @@ class RamanScanUI(QtWidgets.QWidget):
for measIndex, ramanScanIndex in enumerate(cmin):
self.particleContainer.setMeasurementScaneIndex(measIndex, ramanScanIndex)
# self.dataset.ramanscansortindex = cmin
self.dataset.saveParticleData()
self.view.saveDataSet()
self.view.prepareAnalysis()
self.view.scaleImage(2.0)
......@@ -272,8 +270,9 @@ class RamanScanUI(QtWidgets.QWidget):
if i>=0:
self.progressbar.setValue(i+1)
self.view.highLightRamanIndex(i+1)
Npoints = len(self.dataset.ramanpoints)
self.view.highLightRamanIndex(i+1) #go to next scanmarker
Npoints = len(self.dataset.particleContainer.getMeasurementPixelCoords())
if i>3:
timerunning = time()-self.starttime
ttot = timerunning*Npoints/(i+1)
......@@ -286,7 +285,6 @@ class RamanScanUI(QtWidgets.QWidget):
self.dataset.ramanscandone = True
self.view.saveDataSet()
self.view.unblockUI()
# self.view.switchMode("ParticleAnalysis") #directly going to analysis is not feasible... We first have to export spectra etc...
self.progressbar.setValue(0)
self.progressbar.setEnabled(False)
self.progresstime.setEnabled(False)
......
......@@ -100,7 +100,6 @@ class SampleView(QtWidgets.QGraphicsView):
self.update()
def takeScreenshot(self):
#TODO:
#LIMIT SCREENSHOT TO ACTUAL VIEWSIZE OF LOADED IMAGE...
......@@ -179,9 +178,6 @@ class SampleView(QtWidgets.QGraphicsView):
return
assert mode in ["OpticalScan", "ParticleDetection", "RamanScan", "ParticleAnalysis"]
self.oscanwidget.setVisible(False)
if self.detectionwidget is not None:
self.detectionwidget.close()
self.detectionwidget.destroy()
self.ramanwidget.setVisible(False)
self.mode = mode
self.loadPixmap(self.microscopeMode)
......@@ -192,9 +188,9 @@ class SampleView(QtWidgets.QGraphicsView):
elif mode == "ParticleDetection":
if self.detectionwidget is None:
self.detectionwidget = ParticleDetectionView(self.imgdata, self.dataset, self)
self.detectionwidget.show()
self.detectionwidget.imageUpdate.connect(self.detectionUpdate)
self.detectionwidget.detectionFinished.connect(self.activateMaxMode)
self.detectionwidget.show()
elif mode == "RamanScan":
self.ramanwidget.resetDataset(self.dataset)
......@@ -304,7 +300,7 @@ class SampleView(QtWidgets.QGraphicsView):
maxmode = "OpticalScan"
if os.path.exists(self.dataset.getImageName()):
maxmode = "ParticleDetection"
if len(self.dataset.ramanpoints)>0:
if self.dataset.particleDetectionDone:
maxmode = "RamanScan"
if self.dataset.ramanscandone:
maxmode = "ParticleAnalysis"
......@@ -325,11 +321,11 @@ class SampleView(QtWidgets.QGraphicsView):
elif self.mode=="ParticleDetection":
p0 = self.mapToScene(event.pos())
self.detectionwidget.setImageCenter([p0.x(), p0.y()])
else:
p0 = self.mapToScene(event.pos())
super(SampleView, self).mousePressEvent(event)
else:
p0 = self.mapToScene(event.pos())
super(SampleView, self).mousePressEvent(event)
else:
self.particlePainter.mousePressEvent(event)
......
This diff is collapsed.
......@@ -183,6 +183,7 @@ class ScanIndicator(QtWidgets.QGraphicsItem):
painter.drawText(rect, QtCore.Qt.AlignCenter, str(self.number))
painter.drawRect(rect)
class Edge(QtWidgets.QGraphicsItem):
def __init__(self, n1, n2):
......@@ -200,16 +201,16 @@ class Edge(QtWidgets.QGraphicsItem):
def paint(self, painter, option, widget):
painter.setPen(QtCore.Qt.green)
painter.drawLine(self.n1.pos(), self.n2.pos())
class Node(QtWidgets.QGraphicsItem):
def __init__(self, point, view):
self.view = view
self.point = point
self.edges = []
self.rectSize = 60
self.rectSize = 120
super().__init__()
self.setPos(self.point[0], self.point[1])
self.rectSize = 2*self.rectSize #<--- why that? Why not set it to 120 right in the first place??
self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable)
self.setFlag(QtWidgets.QGraphicsItem.ItemSendsGeometryChanges)
self.setCacheMode(QtWidgets.QGraphicsItem.DeviceCoordinateCache)
......@@ -226,9 +227,9 @@ class Node(QtWidgets.QGraphicsItem):
def paint(self, painter, option, widget):
painter.setBrush(QtGui.QColor(255,0,0,80))
painter.setPen(QtCore.Qt.red)
painter.drawLine(0,-self.rectSize/2.,0,self.rectSize/2)
painter.drawLine(-self.rectSize/2.,0,self.rectSize/2,0)
rect = QtCore.QRectF(-self.rectSize,-self.rectSize,2*self.rectSize,2*self.rectSize)
painter.drawLine(0, -self.rectSize/2., 0, self.rectSize/2)
painter.drawLine(-self.rectSize/2., 0, self.rectSize/2, 0)
rect = QtCore.QRectF(-self.rectSize, -self.rectSize, 2*self.rectSize, 2*self.rectSize)
painter.drawEllipse(rect)
def itemChange(self, change, value):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment