2015-09-19 3 views
0

короткой версии:
- взять код, запустите его (все, что вам нужно, это два PNG иконки)
- изменить размер окна, чтобы быть намного больше
- dragndrop один икона (не менее 300+ пикселей)
- затем измените размер окна до исходного размера
- затем попробуйте прокрутить, чтобы увидеть значок, который вы отменили.
- вы не сможете. потому что scrollarea слишком мала.
- почему?PyQt ScrollArea не изменяется после dragndrop

длинная версия:
У меня возникли проблемы с настройкой моей прокрутки, чтобы отразить добавленное или измененное содержимое в моем приложении.
Я показываю значки, я могу их разукрасить.
Если я закрою окно больше, наденьте один значок на дно,
, а затем размер назад мое окно,
scrollarea не позволяет мне прокручивать нижнюю часть, чтобы увидеть мою иконку.
basicaly, как только приложение запустилось, размер прокрутки не изменится.
Как я могу сделать scrollarea, на dragndrop, обновить до нового размера?
он может быть больше, как показано на скриншоте ниже,
или меньше, если все мои значки сгруппированы в верхнем левом углу, например ..
если содержимое поместится в окне, я не покажу ползунок.

вот скриншот, показывающий эту проблему,
это то же самое окно, я просто изменить его размер, и dragndrop один значок в нижней части:

scrollarea_not_updated (ScrollArea не обновляется, так что я не могу прокрутить вниз к моему значок я положил на дно)


вот код до сих пор:

#!/usr/bin/python3 

from PyQt5.QtGui import * 
from PyQt5.QtCore import * 
from PyQt5.QtWidgets import * 
import sys 


class DragWidget(QFrame): 

    def __init__(self, parent=None): 
     super(DragWidget, self).__init__(parent) 

     self.setMinimumSize(200, 200) 
     self.setAcceptDrops(True) 

     test_icon1 = QLabel(self) 
     test_icon1.setPixmap(QPixmap('./images/closeicon.png')) 
     test_icon1.move(20, 20) 
     test_icon1.show() 
     test_icon1.setAttribute(Qt.WA_DeleteOnClose) 

     test_icon2 = QLabel(self) 
     test_icon2.setPixmap(QPixmap('./images/openicon.png')) 
     test_icon2.move(60, 20) 
     test_icon2.show() 
     test_icon2.setAttribute(Qt.WA_DeleteOnClose) 

    def dragEnterEvent(self, event): 
     if event.mimeData().hasFormat('application/x-dnditemdata'): 
      if event.source() == self: 
       event.setDropAction(Qt.MoveAction) 
       event.accept() 
      else: 
       event.acceptProposedAction() 
     else: 
      event.ignore() 

    dragMoveEvent = dragEnterEvent 

    def dropEvent(self, event): 
     if event.mimeData().hasFormat('application/x-dnditemdata'): 
      itemData = event.mimeData().data('application/x-dnditemdata') 
      dataStream = QDataStream(itemData, QIODevice.ReadOnly) 

      pixmap = QPixmap() 
      offset = QPoint() 
      dataStream >> pixmap >> offset 

      newIcon = QLabel(self) 
      newIcon.setPixmap(pixmap) 
      newIcon.move(event.pos() - offset) 
      newIcon.show() 
      newIcon.setAttribute(Qt.WA_DeleteOnClose) 

      if event.source() == self: 
       event.setDropAction(Qt.MoveAction) 
       event.accept() 
      else: 
       event.acceptProposedAction() 
     else: 
      event.ignore() 

    def mousePressEvent(self, event): 
     child = self.childAt(event.pos()) 
     if not child: 
      return 

     pixmap = QPixmap(child.pixmap()) 

     itemData = QByteArray() 
     dataStream = QDataStream(itemData, QIODevice.WriteOnly) 
     dataStream << pixmap << QPoint(event.pos() - child.pos()) 

     mimeData = QMimeData() 
     mimeData.setData('application/x-dnditemdata', itemData) 

     drag = QDrag(self) 
     drag.setMimeData(mimeData) 
     drag.setPixmap(pixmap) 
     drag.setHotSpot(event.pos() - child.pos()) 

     tempPixmap = QPixmap(pixmap) 
     painter = QPainter() 
     painter.begin(tempPixmap) 
     painter.fillRect(pixmap.rect(), QColor(127, 127, 127, 127)) 
     painter.end() 

     child.setPixmap(tempPixmap) 
     if drag.exec_(Qt.CopyAction | Qt.MoveAction) == Qt.MoveAction: 
      child.close() 
     else: 
      child.show() 
      child.setPixmap(pixmap) 


class Window(QWidget): 

    def __init__(self, parent=None): 
     super(Window, self).__init__() 

     widget = QWidget() 
     palette = QPalette() 
     palette.setBrush(QPalette.Background, QBrush(QPixmap("images/pattern.png"))) 
     widget.setPalette(palette) 
     layout = QVBoxLayout(self) 
     layout.addWidget(DragWidget()) 
     widget.setLayout(layout) 
     scroll = QScrollArea() 
     scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) 
     scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) 
     scroll.setWidgetResizable(True) 
     scroll.setWidget(widget) 
     vlayout = QVBoxLayout(self) 
     vlayout.setContentsMargins(0, 0, 0, 0) 
     vlayout.setSpacing(0) 
     vlayout.addWidget(scroll) 
     self.setLayout(vlayout) 
     self.show() 

if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    window = Window('./') 
    sys.exit(app.exec_()) 

ответ

0

оказалось, что мне нужно ed, чтобы изменить метод dropEvent,
, чтобы взять X и Y отброшенной иконки и использовать эти значения для setMinimumSize().
так:

#!/usr/bin/python3 

from PyQt5.QtGui import * 
from PyQt5.QtCore import * 
from PyQt5.QtWidgets import * 
import sys 


class DragWidget(QFrame): 

    def __init__(self, parent=None): 
     super(DragWidget, self).__init__(parent) 

     self.setMinimumSize(200, 200) 
     self.setAcceptDrops(True) 

     self.test_icon1 = QLabel(self) 
     self.test_icon1.setPixmap(QPixmap('./images/closeicon.png')) 
     self.test_icon1.move(20, 20) 
     self.test_icon1.show() 
     self.test_icon1.setAttribute(Qt.WA_DeleteOnClose) 

     self.test_icon2 = QLabel(self) 
     self.test_icon2.setPixmap(QPixmap('./images/openicon.png')) 
     self.test_icon2.move(60, 20) 
     self.test_icon2.show() 
     self.test_icon2.setAttribute(Qt.WA_DeleteOnClose) 

    def dragEnterEvent(self, event): 
     if event.mimeData().hasFormat('application/x-dnditemdata'): 
      if event.source() == self: 
       event.setDropAction(Qt.MoveAction) 
       event.accept() 
      else: 
       event.acceptProposedAction() 
     else: 
      event.ignore() 

    dragMoveEvent = dragEnterEvent 

    def dropEvent(self, event): 
     if event.mimeData().hasFormat('application/x-dnditemdata'): 
      itemData = event.mimeData().data('application/x-dnditemdata') 
      dataStream = QDataStream(itemData, QIODevice.ReadOnly) 

      pixmap = QPixmap() 
      offset = QPoint() 
      dataStream >> pixmap >> offset 

      newIcon = QLabel(self) 
      newIcon.setPixmap(pixmap) 
      newIcon.move(event.pos() - offset) 
      newIcon.show() 
      newIcon.setAttribute(Qt.WA_DeleteOnClose) 

      if newIcon.y()+32 > self.minimumHeight(): 
       self.setMinimumHeight(newIcon.y()+32) 

      if newIcon.x()+32 > self.minimumWidth(): 
       self.setMinimumWidth(newIcon.x()+32) 

      if event.source() == self: 
       event.setDropAction(Qt.MoveAction) 
       event.accept() 
      else: 
       event.acceptProposedAction() 
     else: 
      event.ignore() 

    def mousePressEvent(self, event): 
     child = self.childAt(event.pos()) 
     if not child: 
      return 

     pixmap = QPixmap(child.pixmap()) 

     itemData = QByteArray() 
     dataStream = QDataStream(itemData, QIODevice.WriteOnly) 
     dataStream << pixmap << QPoint(event.pos() - child.pos()) 

     mimeData = QMimeData() 
     mimeData.setData('application/x-dnditemdata', itemData) 

     drag = QDrag(self) 
     drag.setMimeData(mimeData) 
     drag.setPixmap(pixmap) 
     drag.setHotSpot(event.pos() - child.pos()) 

     tempPixmap = QPixmap(pixmap) 
     painter = QPainter() 
     painter.begin(tempPixmap) 
     painter.fillRect(pixmap.rect(), QColor(127, 127, 127, 127)) 
     painter.end() 

     child.setPixmap(tempPixmap) 
     if drag.exec_(Qt.CopyAction | Qt.MoveAction) == Qt.MoveAction: 
      child.close() 
     else: 
      child.show() 
      child.setPixmap(pixmap) 


class Window(QWidget): 

    def __init__(self, parent=None): 
     super(Window, self).__init__() 
     self.pattern = "images/pattern.png" 
     self.widget = QWidget() 
     self.palette = QPalette() 
     self.palette.setBrush(QPalette.Background, QBrush(QPixmap(self.pattern))) 
     self.widget.setPalette(self.palette) 
     layout = QVBoxLayout(self) 
     layout.addWidget(DragWidget()) 
     self.widget.setLayout(layout) 
     scroll = QScrollArea() 
     scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) 
     scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) 
     scroll.setWidgetResizable(True) 
     scroll.setWidget(self.widget) 
     vlayout = QVBoxLayout(self) 
     vlayout.setContentsMargins(0, 0, 0, 0) 
     vlayout.setSpacing(0) 
     vlayout.addWidget(scroll) 
     self.setLayout(vlayout) 
     self.show() 


if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    window = Window('./') 
    window2 = Window('./') 
    sys.exit(app.exec_()) 

примечание метод dropEvent() из DragWidget() класса.

if newIcon.y()+32 > self.minimumHeight(): 
     self.setMinimumHeight(newIcon.y()+32) 

    if newIcon.x()+32 > self.minimumWidth(): 
     self.setMinimumWidth(newIcon.x()+32) 

так, если значок новая позиция больше
MinimumSize (minimumWidth и minimumHeight)
затем добавить смещение self.minimumSize

благодаря Аварису из #pyqt канала для помощи :)

Смежные вопросы