Найти - Пользователи
Полная версия: PyQt4: поворот и drag-and-drop картинок
Начало » GUI » PyQt4: поворот и drag-and-drop картинок
1 2 3 4 5 6 7
gmorgunov
Я конечно извиняюсь за резкий тон. Просто от теории до практики ааагромный шаг. И, надеюсь,всем пишущим здесь
это прекрасно известно. :). А в остальном, надеюсь только на себя. Буду дальше копать.Ну и конечно, в следующий раз не буду спрашивать совета по таким пустякам.
The gray Cardinal
Ну, вобщем, если rotate() применять не к QMatrix, а к QGraphicsPixmapItem, ничего не меняется - картинки портятся, и setRenderHints() для QGraphicsView не помогает:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtGui

class MainWindow(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)

self.scene = QtGui.QGraphicsScene()
view = QtGui.QGraphicsView(self.scene, self)
view.setRenderHints(QtGui.QPainter.Antialiasing | QtGui.QPainter.SmoothPixmapTransform | QtGui.QPainter.HighQualityAntialiasing)
view.setGeometry(0, 0, 500, 350)

pixmap = QtGui.QPixmap(u'011.jpg')
item = self.scene.addPixmap(pixmap)
item.rotate(-25)

pixmap2 = QtGui.QPixmap(u'012.jpg')
item2 = self.scene.addPixmap(pixmap2)
item2.setOffset(100, -30)

pixmap3 = QtGui.QPixmap(u'113.jpg')
item3 = self.scene.addPixmap(pixmap3)
item3.rotate(25)
item3.setOffset(170, -110)

if __name__=="__main__":
app = QtGui.QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
И вопрос в посте #10, кстати, актуален.
Ferroman
imagemagic?
gmorgunov
The Gray Cardinal
Примерно то же самое получилось и у меня.
Это левая часть виджета ( см. выше ) :
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *

class Card(QWidget):

def __init__ (self,*args):
QWidget. __init__ (self,*args)

def paintEvent(self,event=None):
painter=QPainter(self)
image1=QImage("/home/mike/Desktop/lena.jpg")
painter.drawImage(200,100,image1)
image2=QImage("/home/mike/Desktop/av3435.gif")
painter.drawImage(100,100,image2)

app = QApplication(sys.argv)
card = Card()
card.show()
sys.exit(app.exec_())
Это правая:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *

class View(QGraphicsView):
def __init__(self,*args):
QGraphicsView.__init__(self,*args)

def slotRotateLeft (self):
self.rotate(-1)

def slotRotateRight(self):
self.rotate(1)

def Big(self):
self.scale(1.03,1.03)

def Little(self):
self.scale(0.97,0.97)

app = QApplication(sys.argv)
widget = QWidget()
widget.resize(500,500)

scene = QGraphicsScene()
view = View()
pix1 = QPixmap("/home/mike/Desktop/lena.jpg")
pix1.setMask(pix1.mask())
pix1 = scene.addPixmap(pix1.transformed(QMatrix().rotate(-45)))
pix1.setFlags(QGraphicsItem.ItemIsMovable)

pix2 = QPixmap("/home/mike/Desktop/av3435.gif")
pix2.setMask(pix2.mask())
pix2 = scene.addPixmap(pix2.transformed(QMatrix().rotate(45)))
pix2.setFlags(QGraphicsItem.ItemIsMovable)

view = View(scene)

buttonLeft = QPushButton("Left")
buttonRight = QPushButton("Right")
buttonBig = QPushButton("Big")
buttonLittle = QPushButton("Little")

# связываем нажатие кнопкок с функциями
QObject.connect(buttonLeft , SIGNAL("clicked()"),view.slotRotateLeft )
QObject.connect(buttonRight, SIGNAL("clicked()"),view.slotRotateRight)
QObject.connect(buttonBig, SIGNAL("clicked()"),view.Big )
QObject.connect(buttonLittle, SIGNAL("clicked()"),view.Little )

# размещаем виджеты
layout=QVBoxLayout()
layout.addWidget(view)
layout.addWidget(buttonLeft)
layout.addWidget(buttonRight)
layout.addWidget(buttonBig)
layout.addWidget(buttonLittle)
widget.setLayout(layout)

widget.show()
sys.exit(app.exec_())
Осталось:
1) drag_and_drop в левой части.
2) Соединить обе части. :)
3) drag_and_drop между частями.

Если это удастся сделать, тогда и ваша задача решена. (имхо) :)
The gray Cardinal
Мне сильно не нравится качество рисунков после поворота. Кстати, скажем, при повороте на 10 портится сильнее, чем при повороте на 45.
poltergeist
и мне не понравилось, вот это забыл: self.item.setTransformationMode(QtCore.Qt.SmoothTransformation)
import sys
from PyQt4 import QtGui, QtCore

class MainWindow(QtGui.QGraphicsView):
def __init__(self):
QtGui.QGraphicsView.__init__(self)

self.scene = QtGui.QGraphicsScene()
self.setScene(self.scene)

self.setRenderHint(QtGui.QPainter.Antialiasing)
self.setRenderHint(QtGui.QPainter.SmoothPixmapTransform)

pix = QtGui.QPixmap(u'/home/data/images/Beautifull_Batterfly.jpeg')
self.item = self.scene.addPixmap(pix)
self.item.setTransformationMode(QtCore.Qt.SmoothTransformation)

self.t = QtCore.QTimer()
self.connect(self.t, QtCore.SIGNAL('timeout()'), self.rotate)
self.t.start(30)


def rotate(self):
self.item.rotate(.5)





if __name__=="__main__":
app = QtGui.QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
The gray Cardinal
poltergeist
Спасибо, с “self.item.setTransformationMode(QtCore.Qt.SmoothTransformation)” значительно лучше!
Теперь главный вопрос: проблема, озвученная в посте #14, в принципе разрешима?
poltergeist
Конечно. У QLabel как и у всех виджетов прямоугольная форма, которую ну никак не повернуть, поворачивается только изображение на ней, а форма-то остаётся:) С QGraphicsPixmapItem всё по другому, это не виджет, он существует в сцене QGraphicsView и может иметь любую форму:)
The gray Cardinal
poltergeist
Спасибо, ясно. Осталось научиться реализовывать drag-and-drop на сцене. Эх, долго же я буду лопатить доку… :).
The gray Cardinal
Не могу добить пример. Документация, ссылка на которую здесь была приведена выше, практически не помогает, т.к. слишком много общих слов и нет примеров. В результате просто передрал некоторые идеи из примера “dragdroprobot.pyw” (который идёт с PyQt4) и застрял.
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtGui, QtCore

class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setGeometry(300, 300, 600, 500)

# создание сцены для отображения элементов-рисунков:
self.scene = Scene()
# создание виджета представления для отображения сцены:
view = QtGui.QGraphicsView(self.scene, self)
# параметры качества прорисовки для виджета представления:
view.setRenderHints(QtGui.QPainter.Antialiasing | QtGui.QPainter.SmoothPixmapTransform)
self.setCentralWidget(view) # размещение виджета представления в главном окне

# первый элемент:
item = Element(QtGui.QPixmap(u'011.jpg'), None, self.scene)

# второй элемент (с поворотом)
item2 = Element(QtGui.QPixmap(u'113.jpg'), None, self.scene)
item2.rotate(25) # поворот
item2.setOffset(100, -30) # смещение

class Scene(QtGui.QGraphicsScene):
def __init__(self, parent = None):
QtGui.QGraphicsScene.__init__(self, parent)

def dragEnterEvent(self, event):
print 'dragEnterEvent'

def dragLeaveEvent(self, event):
print 'dragLeaveEvent'

def dropEvent(self, event):
print 'dropEvent'

class Element(QtGui.QGraphicsPixmapItem):
def __init__(self, pixmap, parent = None, scene = None):
QtGui.QGraphicsPixmapItem.__init__(self, pixmap, parent, scene)
self.setTransformationMode(QtCore.Qt.SmoothTransformation) # качество прорисовки
self.setCursor(QtCore.Qt.OpenHandCursor) # вид курсора мыши над элементом
#self.setAcceptDrops(True)

def mousePressEvent(self, event):
if event.button() != QtCore.Qt.LeftButton: # только левая клавиша мыши
event.ignore()
return
drag = QtGui.QDrag(event.widget()) # объект Drag
mime = QtCore.QMimeData()
drag.setMimeData(mime)
drag.setPixmap(self.pixmap()) # рисунок, отображающийся в процессе переноса
drag.setHotSpot(QtCore.QPoint(80, 110)) # позиция "ухватки"
drag.start() # запуск (начало) перетаскивания

if __name__=="__main__":
app = QtGui.QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
Я унаследовал свои классы от QGraphicsPixmapItem и от QGraphicsScene. Перетаскивание начинается в процедуре mousePressEvent в классе QGraphicsPixmapItem, а закончится должно по идее где-то в QGraphicsScene (кстати, правильно ли это?).
Вопросы такие:
1. Как определить нужный Z-порядок элементов на сцене? Сама по себе она отрисовывает элементы как придётся.
2. Я запутался в том, что и где надо сделать в классе-наследнике QGraphicsScene, чтобы закончить перетаскивание. Обработчик dropEvent() у меня вообще ни черта не вызывается. И не понятно, как добраться до объекта QDrag, созданного при начале перетаскивания в классе-наследнике QGraphicsPixmapItem.

Добавлено позже:
Первый вопрос - нашёл сам. У объекта QGraphicsPixmapItem есть метод setZValue().
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB