使用PyQt如何让qtpainer使用实现拖放的TableWidget

2024-05-19 22:25:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我实现了一个在单元格之间拖放的表。这是应用程序的精简版本。我想在一些单元格中使用圆角矩形和其他绘图功能。可以看到(运行时),形状只显示在主窗口左上角的一个小窗口中

#! /usr/bin/env python3.6
# -*- coding: utf-8 -*-

import sys

from PyQt5 import QtCore, QtGui, QtWidgets #Just tested it for PyQt4 since I don't have PySide installed...

#
class PaintTable(QtWidgets.QTableWidget):
    def __init__(self, parent):
        QtWidgets.QTableWidget.__init__(self, parent)
        self.center = QtCore.QPoint(-10,-10)
        #self.setAcceptDrops(True)               ## do not pickup drag/drop if assoc with tableWidget
        #self.table.setDragEnabled(True)   ## needs to refer to tablewWidget


    def paintEvent(self, event):

        painter = QtGui.QPainter(self.viewport())
        ##painter.resize(100,200)       
        sizex = self.viewport().width()
        sizey = self.viewport().height()
        #See: http://stackoverflow.com/questions/12226930/overriding-qpaintevents-in-pyqt
        print("Viewport %s # %s # %i / %i"% (self, self.center, sizex, sizey))
        h = int(self.center.y()/50)*50+40
        w = int(self.center.x()/50)*50+25
        a = w-25
        b = h-25
        c = 50
        d = 20
        painter.setPen(QtGui.QPen(QtCore.Qt.green, 5))
        painter.drawRoundedRect((a),(b),(c),(d),10,10)
        line = QtCore.QLineF(w+10.0, h+80.0, w+90.0, h+20.0)
        painter.drawLine(line)
        QtWidgets.QTableWidget.paintEvent(self,event)

    def mousePressEvent(self, event):
        if event.buttons() == QtCore.Qt.RightButton:
            self.center = QtCore.QPoint(event.pos().x(),  event.pos().y())
            print ("at repaint %s" % self.center)
            self.viewport().repaint()

        elif event.buttons() == QtCore.Qt.LeftButton:
            print("In left")
            QtWidgets.QTableWidget.mousePressEvent(self,event)


    def dragMoveEvent(self, e):  # do I need this?
        e.accept(QtCore.QRect(0,0,3000,1800))  ##QRect for moves
        # do not print("in move") from here; will get many

##  locations appear to be related to the upper left corner of the Main Window, not the table

    def dragEnterEvent(self, e):  ## redefined event
      ##
      self.DISPLAY_LOCK = 1  
## 
      was = e.pos()
      print("At top enter %s" % self)
      if (was.x() > 0 and was.x() < self.Wtable) :        
        e.accept()
        wxy = QtCore.QPoint()
        wxy.setX(was.x())
        wxy.setY(was.y()-self.TabYoff)
        print ("newYpos -> %s" % wxy)
##           

    def dropEvent(self, e):  ## redefined event
        print ('drop %s' % self.itemt[0])

#####

class MainWindow(QtWidgets.QMainWindow, QtWidgets.QTableWidget): #, PaintTable ):
    def __init__(self, parent = None):
        super(MainWindow, self).__init__(parent)


# General grid
        self.resize(2400, 1400)

### underlying structure to allow drag and drag to function on the table
        self.cent = QtWidgets.QWidget(PaintTable(self)) ## self      
        self.table = QtWidgets.QTableWidget(self.cent)
        self.setCentralWidget(self.cent)
        self.table.setGeometry(QtCore.QRect(0, 500, 2400, 1400))



        self.setAcceptDrops(True)               ## do not pickup drag/drop if assoc with tableWidget
        self.table.setDragEnabled(True)         ## needs to refer to table

        print("self: %s " % self)
        self.nbrow, self.nbcol = 9, 9
        self.table.setRowCount(self.nbrow)
        self.table.setColumnCount(self.nbcol)
        for row in range(0, self.nbrow):
            self.table.setRowHeight(row, 50)

            for col in range(0, self.nbcol):
                self.table.setColumnWidth(col, 50)

# Each cell contains one single QTableWidgetItem
        for row in range(0, self.nbrow):
            for col in range(0, self.nbcol):
                item = QtWidgets.QTableWidgetItem("#")
                item.setTextAlignment(
                    QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter
                )

                self.table.setItem(row, col, item)

# Header formatting
        font = QtGui.QFont()
        font.setFamily(u"DejaVu Sans")
        font.setPointSize(12)
        self.table.horizontalHeader().setFont(font)
        self.table.verticalHeader().setFont(font)

# Font used
        font = QtGui.QFont()
        font.setFamily(u"DejaVu Sans")
        font.setPointSize(10)
        self.table.setFont(font)

# Global Size (can change size here)
        #self.resize(60*9, 60*9 + 20)

# Layout of the underlying palette
        layout = QtWidgets.QGridLayout()
        layout.addWidget(self.table, 0, 0)
        self.setLayout(layout)

# Set the focus in the first cell
        self.table.setFocus()
        self.table.setCurrentCell(0, 0)

    def dragMoveEvent(self, e):  # do I need this?
        e.accept(QtCore.QRect(0,0,2400,1400))  ##QRect for moves
        # do not print("in move") from here; will get many

##  locations appear to be related to the upper left corner of the Main Window, not the table

    def dragEnterEvent(self, e):  ## redefined event
      ##
      self.DISPLAY_LOCK = 1  
## 
      was = e.pos()
      print("At top enter %s" % self)
      ##if (was.x() > 0 and was.x() < self.Wtable) :        
      e.accept()
      ## wxy = QtCore.QPoint()
      ## wxy.setX(was.x())
      ## wxy.setY(was.y()-self.TabYoff)
      print ("newXYpos -> %s %s" % (was.x(),was.y()))
##           

    def dropEvent(self, e):  ## redefined event
        x="go"
        self.table.setItem(3, 3, QtWidgets.QTableWidgetItem("K"))      
        print ('drop %s' % x)        



if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    fen = MainWindow()
    fen.show()
    sys.exit(app.exec_())        

我有第二个例子,其中我有所需的形状,但这个版本不支持拖放

#! /usr/bin/env python3.6
# -*- coding: utf-8 -*-

import sys

from PyQt5 import QtCore, QtGui, QtWidgets #Just tested it for PyQt4 since I don't have PySide installed...
import sys    
#
#x#class PaintTable(object):
class PaintTable(QtWidgets.QTableWidget):
    def __init__(self, parent):
        QtWidgets.QTableWidget.__init__(self, parent)
        #x#self.table=QtWidgets.QTableWidget()
        print("Create table")
        self.center = QtCore.QPoint(-10,-10)
        ##self.setAcceptDrops(True)         ## does not pickup drag/drop
        ##self.table.setDragEnabled(True)   


    def paintEvent(self, event):
        painter = QtGui.QPainter(self.viewport()) #See: http://stackoverflow.com/questions/12226930/overriding-qpainztevents-in-pyqt
        print("Viewport %s"% self)
        h = int(self.center.y()/50)*50+40
        w = int(self.center.x()/50)*50+25
        a = w-25
        b = h-25
        c = 50
        d = 20
        painter.setPen(QtGui.QPen(QtCore.Qt.green, 5))
        painter.drawRoundedRect((a),(b),(c),(d),10,10)
        line = QtCore.QLineF(w+10.0, h+80.0, w+90.0, h+20.0)
        painter.drawLine(line)
        QtWidgets.QTableWidget.paintEvent(self,event)

    def mousePressEvent(self, event):
        if event.buttons() == QtCore.Qt.RightButton:
            self.center = QtCore.QPoint(event.pos().x(),  event.pos().y())
            print ("at repaint %s" % self.center)
            self.viewport().repaint()

        elif event.buttons() == QtCore.Qt.LeftButton:
            print("In left")
            QtWidgets.QTableWidget.mousePressEvent(self,event)


    def dragMoveEvent(self, e):  # do I need this?
        e.accept(QtCore.QRect(0,0,3000,1800))  ##QRect for moves
        # do not print("in move") from here; will get many

##  locations appear to be related to the upper left corner of the Main Window, not the table

    def dragEnterEvent(self, e):  ## redefined event
      ##
      self.DISPLAY_LOCK = 1  
## 
      was = e.pos()
      print("At top enter %s" % self)
      if (was.x() > 0 and was.x() < self.Wtable) :        
        e.accept()
        wxy = QtCore.QPoint()
        wxy.setX(was.x())
        wxy.setY(was.y()-self.TabYoff)
        print ("newYpos -> %s" % wxy)
##           

    def dropEvent(self, e):  ## redefined event
        print ('drop %s' % self.itemt[0])

#####
#x#class MainWindow(QtWidgets.QTableWidget):
class MainWindow(PaintTable):  ## get graphics on MainWindow, also
    def __init__(self, parent = None):
        super(MainWindow, self).__init__(parent)


# General grid
        #x#self.xxx = PaintTable(self)
        #x#self.table = self.xxx.table
        self.table = PaintTable(self)

        self.setAcceptDrops(True)               ## do not pickup drag/drop if assoc with tableWidget
        self.table.setDragEnabled(True)         ## needs to refer to table

        print("self: %s " % self)
        self.nbrow, self.nbcol = 9, 9
        self.table.setRowCount(self.nbrow)
        self.table.setColumnCount(self.nbcol)
        for row in range(0, self.nbrow):
            self.table.setRowHeight(row, 50)

            for col in range(0, self.nbcol):
                self.table.setColumnWidth(col, 50)

# Each cell contains one single QTableWidgetItem
        for row in range(0, self.nbrow):
            for col in range(0, self.nbcol):
                item = QtWidgets.QTableWidgetItem()
                item.setTextAlignment(
                    QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter
                )

                self.table.setItem(row, col, item)

# Header formatting
        font = QtGui.QFont()
        font.setFamily(u"DejaVu Sans")
        font.setPointSize(12)
        self.table.horizontalHeader().setFont(font)
        self.table.verticalHeader().setFont(font)

# Font used
        font = QtGui.QFont()
        font.setFamily(u"DejaVu Sans")
        font.setPointSize(20)
        self.table.setFont(font)

# Global Size
        self.resize(60*9, 60*9 + 20)

# Layout of the table
        layout = QtWidgets.QGridLayout()
        layout.addWidget(self.table, 0, 0)
        self.setLayout(layout)

# Set the focus in the first cell
        self.table.setFocus()
        self.table.setCurrentCell(0, 0)

##### drag routines
    def dragMoveEvent(self, e):  # do I need this?
        e.accept(QtCore.QRect(0,0,3000,1800))  ##QRect for moves
        # do not print("in move") from here; will get many

##  locations appear to be related to the upper left corner of the Main Window, not the table

    def dragEnterEvent(self, e):  ## redefined event
      ##
      self.DISPLAY_LOCK = 1  
## 
      was = e.pos()
      print("At top enter %s" % self)
      if (was.x() > 0 and was.x() < self.Wtable) :        
        e.accept()
        wxy = QtCore.QPoint()
        wxy.setX(was.x())
        wxy.setY(was.y()-self.TabYoff)
        print ("newYpos -> %s" % wxy)
##           

    def dropEvent(self, e):  ## redefined event
        print ('drop %s' % self.itemt[0])        



if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    fen = MainWindow()
    fen.show()
    sys.exit(app.exec_())        

需要什么结构来获得形状的叠加和拖放功能


Tags: thetoinselfeventfordeftable