计算机系统应用教程网站

网站首页 > 技术文章 正文

Python+PyQt5进阶(5) pyqt5 django

btikc 2024-10-20 05:05:27 技术文章 9 ℃ 0 评论

本篇介绍PyQt5中的自定义对话框,有时候为了完成一些特定的功能,可能需要自己设定自定义对话框。自定义对话框一般继承QDialog类,可以在UI designer中设计。

本篇介绍一个QTableWidget控件,使用自定义对话框对其操作。本Demo总共有四个ui文件,三个QDialog文件,一个主窗口QMainWindow。

窗口介绍

  • QMainWindow主窗口。

顶部三个ToolButton设置表格的格式表头等。中间部分一个QTableWidget控件,预先在UI designer中设置其单元格内容,底部是一个QStatusBar状态栏显示单元格的位置及内容。

  • DialogSize设置行数/列数对话框。
  • DialogHeader设置表头对话框。放置一个ListView控件。
  • DialogLocate定位单元格对话框。

主窗口QMainWindow

  • 自定义一个槽函数,当前单元格发生改变的时候发生信号。在DialogLocate对话框内使用。
cellIndexChanged = pyqtSignal(int, int)
    def currentChanged(self, current, previous):
        try:
            if current is not None:
                self.label1.setText("当前单元格:%d行, %d列" % (current.row(), current.column()))
            item = self.tableWidget.itemFromIndex(current)
            self.label2.setText("单元格内容:" + item.text())
            self.cellIndexChanged.emit(current.row(), current.column())
        except Exception as e:
            print(e)

DialogSize对话框

  • 给确定和取消按钮关联槽函数。
  • 自定义一个DialogSize类,继承QDialog。
class NewDialogSize(QDialog):
    def __init__(self, rowcount=3, columncount=5, parent=None):
        super().__init__(parent)
        self.Dialog = Ui_Dialog()
        self.Dialog.setupUi(self)
        self.setWindowFlag(Qt.MSWindowsFixedSizeDialogHint)

    def __del__(self):
        print("对象被删除")

    def initDialog(self, rowcount, columncount):
        self.Dialog.spinBox.setValue(rowcount)
        self.Dialog.spinBox_2.setValue(columncount)

    def getTableSize(self):
        row = self.Dialog.spinBox.value()
        column = self.Dialog.spinBox_2.value()
        return row, column
  • 主窗口中设置行数/列数按钮的槽函数。
  1. myDialog = NewDialogSize():先实例化NewDialogSize()。
  2. myDialog.initDialog(7, 4):初始化对话框,设置两个SpinBox的值。
  3. ret = myDialog.exec_():以模态方式显示对话框,模态显示下,用户只能操作对话框,别的窗口无法操作。主程序只能等待exec_()函数返回的结果。
  4. row, col = myDialog.getTableSize():返回SpinBox内的数值。
def btnSetRow_clicked(self):
    myDialog = NewDialogSize()
    myDialog.initDialog(7, 4)
    ret = myDialog.exec_()
    if ret == QDialog.Accepted:
        row, col = myDialog.getTableSize()
        self.tableWidget.setRowCount(row)
        self.tableWidget.setColumnCount(col)

DialogHeader对话框

  • 给确定和取消按钮关联槽函数。
  • 自定义一个DialogHeader类,继承QDialog。
class newDialogHeader(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.Dialog1 = Ui_Dialog1()
        self.Dialog1.setupUi(self)
        self.setWindowFlag(Qt.MSWindowsFixedSizeDialogHint)
        self.model = QStringListModel()
        self.Dialog1.listView.setModel(self.model)
        self.Dialog1.listView.setAlternatingRowColors(True)
        self.Dialog1.listView.setDragDropMode(QAbstractItemView.InternalMove)
        self.Dialog1.listView.setDefaultDropAction(Qt.MoveAction)

    def __del__(self):
        print("对象1被删除")

    def setHeader(self, HeaderStrList):
        self.model.setStringList(HeaderStrList)

    def headerList(self):
        return self.mheadodel.stringList()
  • 主窗口中设置表头按钮的槽函数。
  1. self.setHeaderFlag = newDialogHeader(self):实例化newDialogHeader()。
  2. count = len(self.setHeaderFlag.headerList()):调用headerList()函数,读取listView中的列表长度。
  3. header = self.tableWidget.horizontalHeaderItem(i).text():for循环读取主界面tableWidget的列表头。
  4. self.setHeaderFlag.setHeader(strList):调用setHeader()函数。
  5. strList2 = self.setHeaderFlag.headerList():如果点击确定按钮,重新获取当前对话框内的数据。
  6. self.tableWidget.setHorizontalHeaderLabels(strList2):设置表头。
def btnSetHeader_clicked(self):
    try:
        if self.setHeaderFlag is None:
            self.setHeaderFlag = newDialogHeader(self)
        count = len(self.setHeaderFlag.headerList())
        if count != self.tableWidget.columnCount():
            strList = []
            for i in range(self.tableWidget.columnCount()):
                header = self.tableWidget.horizontalHeaderItem(i).text()
                strList.append(header)
            self.setHeaderFlag.setHeader(strList)
        ret = self.setHeaderFlag.exec_()
        if ret == QDialog.Accepted:
            strList2 = self.setHeaderFlag.headerList()
            self.tableWidget.setHorizontalHeaderLabels(strList2)
    except Exception as e:
        print(e)

DialogLocate对话框

前面两个都是以模态方式运行对话框,以中断的方式中断主窗口,只有对话框退出,才能操作主窗口。这个对话框使用QDialog.show()方式显示对话框。

定义两个信号:changeAction和changeCellText。

  • changeAction:当定位按钮按下,会发射一个bool类型信号,setActionEnable()函数会让定位按钮是否可以。
  • changeCellText:当选择的单元格改变,会发生当前的行号、列号和单元格内容。
class newDialog3(QDialog):
    changeAction = pyqtSignal(bool)
    changeCellText = pyqtSignal(int, int, str)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.Dialog2 = Ui_Dialog2()
        self.Dialog2.setupUi(self)
        self.setWindowFlag(Qt.WindowStaysOnTopHint)
        self.Dialog2.pushButton.clicked.connect(self.btnAccept_clicked)
        self.Dialog2.pushButton_2.clicked.connect(self.reject)

    def __del__(self):
        print("对象2被删除")

    def setSpinBoxRange(self, rowcount, columncount):
        self.Dialog2.spinBox.setMaximum(columncount-1)
        self.Dialog2.spinBox_2.setMaximum(rowcount-1)

    def showEvent(self, event):
        print("showEvent")
        self.changeAction.emit(False)
        super().showEvent(event)

    def closeEvent(self, event):
        print("closeEvent")
        self.changeAction.emit(True)
        super().closeEvent(event)

    def btnAccept_clicked(self):
        row = self.Dialog2.spinBox_2.value()
        col = self.Dialog2.spinBox.value()
        text = self.Dialog2.lineEdit.text()
        self.changeCellText.emit(row, col, text)
        if self.Dialog2.checkBox_2.isChecked():
            self.Dialog2.spinBox_2.setValue(self.Dialog2.spinBox_2.value()+1)
        if self.Dialog2.checkBox.isChecked():
            self.Dialog2.spinBox.setValue(self.Dialog2.spinBox.value()+1)

    def do_setSpinValue(self, rowNum, colNum):
        try:
            print(rowNum, colNum)
            self.Dialog2.spinBox.setValue(colNum)
            self.Dialog2.spinBox_2.setValue(rowNum)
        except TypeError as e:
            print(e)
  • 主窗口中设置表头按钮的槽函数。

当定位按钮按下,弹出对话框。选择的单元格发生变化,三个槽函数运行,在DialogLocate中显示行号。

def btnSetLocate_clicked(self):
    dialogLocate = newDialog3(self)
    dialogLocate.do_setSpinValue(10, 5)
    dialogLocate.changeCellText.connect(self.setCellText)
    dialogLocate.changeAction.connect(self.setActionEnable)
    self.cellIndexChanged.connect(dialogLocate.do_setSpinValue)
    dialogLocate.setAttribute(Qt.WA_DeleteOnClose)
    dialogLocate.show()
def do_currentChanged(self, current, previous):
    try:
        if current is not None:
            self.label1.setText("当前单元格:%d行, %d列" % (current.row(), current.column()))
        # item = self.tableWidget.currentItem(current)
        self.label2.setText("单元格内容:" + current.text())
        self.cellIndexChanged.emit(current.row(), current.column())
    except Exception as e:
        print(e)

  def setActionEnable(self, enable):
      try:
          self.toolButton_3.setEnabled(enable)
      except Exception as e:
          print(e)

def setCellText(self, row, column, text):
    try:
        item = QTableWidgetItem(text, 3)
        self.tableWidget.setItem(row, column, item)
    except Exception as e:
        print(e)

一个简单的案例介绍自定义对话框的使用,如果需要源代码可关注私聊,感谢支持!!!!

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表