打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
用 eric6 与 PyQt5 实现python的极速GUI编程

用 eric6 与 PyQt5 实现python的极速GUI编程(系列03)---- Drawing(绘图)(1)-- 绘写文字


【概览】

本文实现如下的程序:(在窗体中绘画出文字

 

主要步骤如下:

1、在eric6中新建项目,新建窗体

2、(自动打开)进入PyQt5 Desinger,编辑图形界面,保存

3、回到eric 6,对上一步得到的界面文件 drawing.ui 文件右击,编译窗体,得到 Ui_drawing.py 文件

4、然后再对 drawing.ui 文件右击,生成对话框代码,得到 drawing.py 文件。(在drawing.py中添加自己的程序逻辑

5、py2exe打包成exe文件(此步略)

 

【正文】

接【概览】第4步:

在 drawing.py 中,先准备要绘画的文本(self.text):

    def __init__(self, parent=None):         # ...        self.text = '\u041b\u0435\u0432 \u041d\u0438\u043a\u043e\u043b\u0430\\u0435\u0432\u0438\u0447 \u0422\u043e\u043b\u0441\u0442\u043e\u0439: \n\\u0410\u043d\u043d\u0430 \u041a\u0430\u0440\u0435\u043d\u0438\u043d\u0430'

 

然后定义一个绘画事件:

    def paintEvent(self, event):        ...

所有的绘画都发生在此绘画事件内。给此绘画事件添加四行代码!

        qp = QtGui.QPainter()        qp.begin(self)        self.drawText(event, qp)#自定义的绘画方法        qp.end()

QtGui.QPainter类负责所有低级别的绘画。

所有的绘画方法要放在 begin()end() 方法之间。当然,这里我们放的是自定义的drawText()方法

 

上面代码合起来是这样的:

    def paintEvent(self, event):        qp = QtGui.QPainter()        qp.begin(self)        self.drawText(event, qp)#自定义的绘画方法        qp.end()

后面的几篇关于绘画的文章中,上面这一坨代码几乎就不变了

当然了,变的是自定义的drawText方法:

    def drawText(self, event, qp):        qp.setPen(QtGui.QColor(168, 34, 3))#设置笔的颜色        qp.setFont(QtGui.QFont('Decorative', 20))#设置字体        qp.drawText(event.rect(), QtCore.Qt.AlignCenter, self.text)#画出文本

 

最终的 drawing.py 是这样的:

# -*- coding: utf-8 -*-'''Module implementing Drawing.'''import sysfrom PyQt5 import  QtGui, QtCorefrom PyQt5.QtWidgets import QDialog, QApplicationfrom Ui_drawing import Ui_drawingclass Drawing(QDialog, Ui_Drawing):    def __init__(self, parent=None):        super(Drawing, self).__init__(parent)        self.setupUi(self)                self.text = '\u041b\u0435\u0432 \u041d\u0438\u043a\u043e\u043b\u0430\\u0435\u0432\u0438\u0447 \u0422\u043e\u043b\u0441\u0442\u043e\u0439: \n\\u0410\u043d\u043d\u0430 \u041a\u0430\u0440\u0435\u043d\u0438\u043d\u0430'    def paintEvent(self, event):        qp = QtGui.QPainter()        qp.begin(self)        self.drawText(event, qp)        qp.end()            def drawText(self, event, qp):        qp.setPen(QtGui.QColor(168, 34, 3))        qp.setFont(QtGui.QFont('Decorative', 20))        qp.drawText(event.rect(), QtCore.Qt.AlignCenter, self.text)if __name__ == '__main__':    app = QApplication(sys.argv)    dlg = Drawing()    dlg.show()    sys.exit(app.exec_())

 

用 eric6 与 PyQt5 实现python的极速GUI编程(系列03)---- Drawing(绘图)(2)-- 画点

【概览】

本文实现如下的程序:(在窗体中绘画出[-100, 100]两个周期的正弦函数图像

 

主要步骤如下:

1、在eric6中新建项目,新建窗体

2、(自动打开)进入PyQt5 Desinger,编辑图形界面,保存

3、回到eric 6,对上一步得到的界面文件 drawing.ui 文件右击,编译窗体,得到 Ui_drawing.py 文件

4、然后再对 drawing.ui 文件右击,生成对话框代码,得到 drawing.py 文件。(在drawing.py中添加自己的程序逻辑

5、py2exe打包成exe文件(此步略)

 

【正文】

接【概览】第4步:

在 drawing.py 中,先定义绘画事件:

    def paintEvent(self, event):        qp = QtGui.QPainter()        qp.begin(self)        self.drawPoints(qp) #自定义画点方法        qp.end()

然后,自定义画点方法:

    def drawPoints(self,  qp):        qp.setPen(QtCore.Qt.red)        size = self.size()                for i in range(1000):            # [-100, 100]两个周期的正弦函数图像            x = 100 *(-1 2.0*i/1000)  size.width()/2.0            y = -50*math.sin((x - size.width()/2.0)*math.pi/50)   size.height()/2.0            qp.drawPoint(x, y)

合起来,drawing.py 是这个样子:

# -*- coding: utf-8 -*-'''Module implementing Drawing.'''import sys, mathfrom PyQt5 import  QtGui, QtCorefrom PyQt5.QtWidgets import QDialog, QApplicationfrom Ui_drawing import Ui_Drawingclass Drawing(QDialog, Ui_Drawing):    def __init__(self, parent=None):        super(Drawing, self).__init__(parent)        self.setupUi(self)    def paintEvent(self, event):        qp = QtGui.QPainter()        qp.begin(self)        self.drawPoints(qp)#自定义画点方法        qp.end()            def drawPoints(self,  qp):        qp.setPen(QtCore.Qt.red)        size = self.size()                for i in range(1000):            # [-100, 100]两个周期的正弦函数图像            x = 100 *(-1 2.0*i/1000)  size.width()/2.0            y = -50*math.sin((x - size.width()/2.0)*math.pi/50)   size.height()/2.0            qp.drawPoint(x, y)if __name__ == '__main__':    app = QApplication(sys.argv)    dlg = Drawing()    dlg.show()    sys.exit(app.exec_())

 

用 eric6 与 PyQt5 实现python的极速GUI编程(系列03)---- Drawing(绘图)(3)-- 画线

【概览】

本文实现如下的程序:(在窗体中绘画出各种不同风格的线条

 

主要步骤如下:

1、在eric6中新建项目,新建窗体

2、(自动打开)进入PyQt5 Desinger,编辑图形界面,保存

3、回到eric 6,对上一步得到的界面文件 drawing.ui 文件右击,编译窗体,得到 Ui_drawing.py 文件

4、然后再对 drawing.ui 文件右击,生成对话框代码,得到 drawing.py 文件。(在drawing.py中添加自己的程序逻辑

5、py2exe打包成exe文件(此步略)

 

【正文】

接【概览】第4步:

在 drawing.py 中,先定义绘画事件:

    def paintEvent(self, event):        qp = QtGui.QPainter()        qp.begin(self)        self.drawLines(qp) #自定义的画线方法        qp.end()

然后,自定义画线方法:

    def drawLines(self,  qp):        pen = QtGui.QPen(QtCore.Qt.black, 2, QtCore.Qt.SolidLine)        qp.setPen(pen)        qp.drawLine(20, 40, 250, 40)        pen.setStyle(QtCore.Qt.DashLine)        qp.setPen(pen)        qp.drawLine(20, 80, 250, 80)        pen.setStyle(QtCore.Qt.DashDotLine)        qp.setPen(pen)        qp.drawLine(20, 120, 250, 120)        pen.setStyle(QtCore.Qt.DotLine)        qp.setPen(pen)        qp.drawLine(20, 160, 250, 160)        pen.setStyle(QtCore.Qt.DashDotDotLine)        qp.setPen(pen)        qp.drawLine(20, 200, 250, 200)        pen.setStyle(QtCore.Qt.CustomDashLine)        pen.setDashPattern([1, 4, 5, 4])        qp.setPen(pen)        qp.drawLine(20, 240, 250, 240)

合起来,drawing.py 是这个样子:

# -*- coding: utf-8 -*-'''Module implementing Drawing.'''import sysfrom PyQt5 import  QtGui, QtCorefrom PyQt5.QtWidgets import QDialog, QApplicationfrom Ui_drawing import Ui_Drawingclass Drawing(QDialog, Ui_Drawing):    def __init__(self, parent=None):        super(Drawing, self).__init__(parent)        self.setupUi(self)    def paintEvent(self, event):        qp = QtGui.QPainter()        qp.begin(self)        self.drawLines(qp)        qp.end()    def drawLines(self,  qp):        pen = QtGui.QPen(QtCore.Qt.black, 2, QtCore.Qt.SolidLine)        qp.setPen(pen)        qp.drawLine(20, 40, 250, 40)        pen.setStyle(QtCore.Qt.DashLine)        qp.setPen(pen)        qp.drawLine(20, 80, 250, 80)        pen.setStyle(QtCore.Qt.DashDotLine)        qp.setPen(pen)        qp.drawLine(20, 120, 250, 120)        pen.setStyle(QtCore.Qt.DotLine)        qp.setPen(pen)        qp.drawLine(20, 160, 250, 160)        pen.setStyle(QtCore.Qt.DashDotDotLine)        qp.setPen(pen)        qp.drawLine(20, 200, 250, 200)        pen.setStyle(QtCore.Qt.CustomDashLine)        pen.setDashPattern([1, 4, 5, 4])        qp.setPen(pen)        qp.drawLine(20, 240, 250, 240)if __name__ == '__main__':    app = QApplication(sys.argv)    dlg = Drawing()    dlg.show()    sys.exit(app.exec_())

 

用 eric6 与 PyQt5 实现python的极速GUI编程(系列04)---- PyQt5自带教程:地址簿(address book)

【引子】

在PyQt5自带教程中,地址簿(address book)程序没有完全实现界面与业务逻辑分离。

本文我打算用eric6 PyQt5对其进行改写,以实现界面与逻辑完全分离。

 

【概览】


1、界面:


2、功能简介:
程序有三种操作模式:浏览模式、添加模式、编辑模式。 其实现的功能都显式的体现在各个按钮上


3、主要步骤:
1)、在eric6中新建项目,新建窗体,取名为 addressbook.ui 文件

2)、(自动打开)进入PyQt5 Desinger,编辑图形界面,保存

3)、回到eric 6,对上一步得到的界面文件 addressbook.ui 文件右击,编译窗体,得到 Ui_addressbook.py 文件

4)、然后再对 addressbook.ui 文件右击,生成对话框代码,得到 addressbook.py 文件。(在addressbook.py中添加自己的程序逻辑)

5)、py2exe打包成exe文件(此步略)


4、涉及的知识点:
import sys, pickle

from PyQt5.QtCore import pyqtSlot, QFile, QIODevice, Qt, QTextStream
from PyQt5.QtWidgets import QWidget, QDialog, QLabel, QLineEdit, QPushButton, QHBoxLayout,  QMessageBox, QFileDialog,  QApplication



【正文】
1、一般的步骤省略不表,接上面主要步骤第二步:

在Qt设计师中,将行编辑框(lineEdit)、文本编辑框(textEdit)、及十一个按钮(pushButton)的对象名(objectName)分别设置如下:

lineEdit_name(姓名输入框)

textEdit_address(地址输入框)

pushButton_add(添加 按钮)

pushButton_edit(编辑 按钮)

pushButton_remove(删除 按钮)

pushButton_find(查找 按钮)

pushButton_submit(提交 按钮)

pushButton_cancel(取消 按钮)

pushButton_load(导入 按钮)

pushButton_save(保存 按钮)

pushButton_export(导出 按钮)

pushButton_previous(前一个 按钮)

pushButton_next(后一个 按钮)

 

2、关闭Qt设计师,回到eric6

先右击addressbook.ui 文件,编译窗体,得到 Ui_addressbook.py 文件

然后再次右击addressbook.ui 文件,生成对话框代码,

在弹窗中勾选十一个按钮的 on_x_clicked() 事件,确定,得到 addressbook.py 文件。

 

3、对addressbook.py 文件执行下面四步处理

1)、清空所有注释

2)、去掉一个多余的点,将

from .Ui_addressbook import Ui_Form

变成:

from Ui_addressbook import Ui_Form

3)、将所有clicked()下的代码改写为pass

    @pyqtSlot()    def on_pushButton_add_clicked(self):        pass        @pyqtSlot()    def on_pushButton_edit_clicked(self):        pass        # ...

4)、在 addressbook.py 文件最后面加上下面几句代码:

if __name__ == '__main__':    import sys    from PyQt5.QtWidgets import QApplication        app = QApplication(sys.argv)    dlg = Dialog()    dlg.show()    sys.exit(app.exec_())

最后,addressbook.py 看起来是这个样子:

 1 # -*- coding: utf-8 -*- 2  3 from PyQt5.QtCore import pyqtSlot 4 from PyQt5.QtWidgets import QDialog 5  6 from Ui_addressbook import Ui_Dialog 7  8  9 class Dialog(QDialog, Ui_Dialog):10     def __init__(self, parent=None):11         super(Dialog, self).__init__(parent)12         self.setupUi(self)13     14     @pyqtSlot()15     def on_pushButton_add_clicked(self):16         pass17     18     @pyqtSlot()19     def on_pushButton_edit_clicked(self):20         pass21     22     @pyqtSlot()23     def on_pushButton_remove_clicked(self):24         pass25     26     @pyqtSlot()27     def on_pushButton_find_clicked(self):28         pass29     30     @pyqtSlot()31     def on_pushButton_submit_clicked(self):32         pass33     34     @pyqtSlot()35     def on_pushButton_cancel_clicked(self):36         pass37     38     @pyqtSlot()39     def on_pushButton_load_clicked(self):40         pass41     42     @pyqtSlot()43     def on_pushButton_save_clicked(self):44         pass45     46     @pyqtSlot()47     def on_pushButton_export_clicked(self):48         pass49     50     @pyqtSlot()51     def on_pushButton_previous_clicked(self):52         pass53     54     @pyqtSlot()55     def on_pushButton_next_clicked(self):56         pass57 58 if __name__ == '__main__':59     import sys60     from PyQt5.QtWidgets import QApplication61     62     app = QApplication(sys.argv)63     dlg = Dialog()64     dlg.show()65     sys.exit(app.exec_())

View Code

 

4、下面添加逻辑代码

# -*- coding: utf-8 -*-import picklefrom PyQt5.QtCore import pyqtSlot, QFile, QIODevice, Qt, QTextStreamfrom PyQt5.QtWidgets import QWidget, QDialog, QLabel, QLineEdit, QPushButton, QHBoxLayout,  QMessageBox, QFileDialogfrom Ui_addressbook import Ui_Dialogclass SortedDict(dict):    class Iterator(object):        def __init__(self, sorted_dict):            self._dict = sorted_dict            self._keys = sorted(self._dict.keys())            self._nr_items = len(self._keys)            self._idx = 0        def __iter__(self):            return self        def next(self):            if self._idx >= self._nr_items:                raise StopIteration            key = self._keys[self._idx]            value = self._dict[key]            self._idx  = 1            return key, value        __next__ = next    def __iter__(self):        return SortedDict.Iterator(self)    iterkeys = __iter__class FindDialog(QDialog):    def __init__(self, parent=None):        super(FindDialog, self).__init__(parent)        findLabel = QLabel('输入要查找的联系人姓名:')        self.lineEdit = QLineEdit()        self.findButton = QPushButton('查找')        self.findText = ''        layout = QHBoxLayout()        layout.addWidget(findLabel)        layout.addWidget(self.lineEdit)        layout.addWidget(self.findButton)        self.setLayout(layout)        self.setWindowTitle('查找联系人')        self.findButton.clicked.connect(self.findClicked)        self.findButton.clicked.connect(self.accept)    def findClicked(self):        text = self.lineEdit.text()        if not text:            QMessageBox.information(self, '姓名不能为空', '请输入一个姓名')            return        self.findText = text        self.lineEdit.clear()        self.hide()    def getFindText(self):        return self.findTextclass Dialog(QDialog, Ui_Dialog):    NavigationMode, AddingMode, EditingMode = range(3)        def __init__(self, parent=None):        super(Dialog, self).__init__(parent)        self.setupUi(self)                self.pushButton_submit.hide()        self.pushButton_cancel.hide()                self.contacts = SortedDict()        self.oldName = ''        self.oldAddress = ''        self.currentMode = self.NavigationMode                self.dialog = FindDialog()        @pyqtSlot()    def on_pushButton_add_clicked(self):        self.oldName = self.lineEdit_name.text()        self.oldAddress = self.textEdit_address.toPlainText()                self.lineEdit_name.clear()        self.textEdit_address.clear()                self.updateInterface(self.AddingMode)            @pyqtSlot()    def on_pushButton_edit_clicked(self):        self.oldName = self.lineEdit_name.text()        self.oldAddress = self.textEdit_address.toPlainText()        self.updateInterface(self.EditingMode)        @pyqtSlot()    def on_pushButton_remove_clicked(self):        name = self.lineEdit_name.text()        address = self.textEdit_address.toPlainText()        if name in self.contacts:            button = QMessageBox.question(self, '确定删除','你真的确定要删除 {} 吗?'.format(name), QMessageBox.Yes | QMessageBox.No)            if button == QMessageBox.Yes:                self.on_pushButton_previous_clicked()                del self.contacts[name]                QMessageBox.information(self, '删除成功','{}已经从你的地址簿删除了!'.format(name))        self.updateInterface(self.NavigationMode)        @pyqtSlot()    def on_pushButton_find_clicked(self):        self.dialog.show()        if self.dialog.exec_() == QDialog.Accepted:            contactName = self.dialog.getFindText()            if contactName in self.contacts:                self.lineEdit_name.setText(contactName)                self.textEdit_address.setText(self.contacts[contactName])            else:                QMessageBox.information(self, '找不到','抱歉,{}不在你的地址簿内!'.format(contactName))                return        self.updateInterface(self.NavigationMode)        @pyqtSlot()    def on_pushButton_submit_clicked(self):        name = self.lineEdit_name.text()        address = self.textEdit_address.toPlainText()        if name == '' or address == '':            QMessageBox.information(self, '不能为空', '请输入姓名及地址!')            return        if self.currentMode == self.AddingMode:            if name not in self.contacts:                self.contacts[name] = address                QMessageBox.information(self, '添加成功', '{} 已经添加到你的地址簿!'.format(name))            else:                QMessageBox.information(self, '添加失败', '{} 已经存在于你的地址簿!'.format(name))                return        elif self.currentMode == self.EditingMode:            if self.oldName != name:                if name not in self.contacts:                    QMessageBox.information(self, '编辑成功','{} 已经被编辑到你的地址簿!'.format(self.oldName))                                        del self.contacts[self.oldName]                    self.contacts[name] = address                else:                    QMessageBox.information(self, '编辑失败','抱歉,{} 已经存在于你的地址簿!'.format(name))                    return            elif self.oldAddress != address:                QMessageBox.information(self, '编辑成功','{} 已经被编辑到你的地址簿!'.format(name))                self.contacts[name] = address        self.updateInterface(self.NavigationMode)        @pyqtSlot()    def on_pushButton_cancel_clicked(self):        self.lineEdit_name.setText(self.oldName)        self.textEdit_address.setText(self.oldAddress)                self.updateInterface(self.NavigationMode)            @pyqtSlot()    def on_pushButton_load_clicked(self):        fileName, _ = QFileDialog.getOpenFileName(self, '打开地址簿', '', '地址簿文件 (*.abk);;所有文件 (*)')        if not fileName:            return        try:            in_file = open(str(fileName), 'rb')        except IOError:            QMessageBox.information(self, '不能打开文件','打开文件 {} 时发生错误!'.format(fileName))            return        self.contacts = pickle.load(in_file)        in_file.close()        if len(self.contacts) == 0:            QMessageBox.information(self, '文件中无联系人','你打开的文件中无联系人!')        else:            for name, address in self.contacts:                self.lineEdit_name.setText(name)                self.textEdit_address.setText(address)        self.updateInterface(self.NavigationMode)            @pyqtSlot()    def on_pushButton_save_clicked(self):        fileName, _ = QFileDialog.getSaveFileName(self, '保存地址簿', '', '地址簿文件 (*.abk);;所有文件 (*)')        if not fileName:            return        try:            out_file = open(str(fileName), 'wb')        except IOError:            QMessageBox.information(self, '不能打开文件','打开文件 {} 时发生错误!'.format(fileName))            return        pickle.dump(self.contacts, out_file)        out_file.close()            @pyqtSlot()    def on_pushButton_export_clicked(self):        name = str(self.lineEdit_name.text())        address = self.textEdit_address.toPlainText()        nameList = name.split()        if len(nameList) > 1:            firstName = nameList[0]            lastName = nameList[-1]        else:            firstName = name            lastName = ''        fileName, _ = QFileDialog.getSaveFileName(self, '导出联系', '', 'vCard 文件 (*.vcf);;所有文件 (*)')        if not fileName:            return        out_file = QFile(fileName)        if not out_file.open(QIODevice.WriteOnly):            QMessageBox.information(self, '不能打开文件', out_file.errorString())            return        out_s = QTextStream(out_file)        out_s << 'BEGIN:VCARD' << '\n'        out_s << 'VERSION:2.1' << '\n'        out_s << 'N:' << lastName << ';' << firstName << '\n'        out_s << 'FN:' << ' '.join(nameList) << '\n'        address.replace(';', '\\;')        address.replace('\n', ';')        address.replace(',', ' ')        out_s << 'ADR;HOME:;' << address << '\n'        out_s << 'END:VCARD' << '\n'        QMessageBox.information(self, '导出成功','{} 已经被导出为 vCard !'.format(name))    @pyqtSlot()    def on_pushButton_previous_clicked(self):        name = self.lineEdit_name.text()        prev_name = prev_address = None        for this_name, this_address in self.contacts:            if this_name == name:                break            prev_name = this_name            prev_address = this_address        else:            self.lineEdit_name.clear()            self.textEdit_address.clear()            return        if prev_name is None:            for prev_name, prev_address in self.contacts:                pass        self.lineEdit_name.setText(prev_name)        self.textEdit_address.setText(prev_address)            @pyqtSlot()    def on_pushButton_next_clicked(self):        name = self.lineEdit_name.text()        it = iter(self.contacts)        try:            while True:                this_name, _ = it.next()                if this_name == name:                    next_name, next_address = it.next()                    break        except StopIteration:            next_name, next_address = iter(self.contacts).next()        self.lineEdit_name.setText(next_name)        self.textEdit_address.setText(next_address)        def updateInterface(self, mode):        self.currentMode = mode        if self.currentMode in (self.AddingMode, self.EditingMode):            self.lineEdit_name.setReadOnly(False)            self.lineEdit_name.setFocus(Qt.OtherFocusReason)            self.textEdit_address.setReadOnly(False)            self.pushButton_add.setEnabled(False)            self.pushButton_edit.setEnabled(False)            self.pushButton_remove.setEnabled(False)            self.pushButton_next.setEnabled(False)            self.pushButton_previous.setEnabled(False)            self.pushButton_submit.show()            self.pushButton_cancel.show()            self.pushButton_load.setEnabled(False)            self.pushButton_save.setEnabled(False)            self.pushButton_export.setEnabled(False)        elif self.currentMode == self.NavigationMode:            if not self.contacts:                self.lineEdit_name.clear()                self.textEdit_address.clear()            self.lineEdit_name.setReadOnly(True)            self.textEdit_address.setReadOnly(True)            self.pushButton_add.setEnabled(True)            number = len(self.contacts)            self.pushButton_edit.setEnabled(number >= 1)            self.pushButton_remove.setEnabled(number >= 1)            self.pushButton_find.setEnabled(number > 2)            self.pushButton_next.setEnabled(number > 1)            self.pushButton_previous.setEnabled(number >1 )            self.pushButton_submit.hide()            self.pushButton_cancel.hide()            self.pushButton_export.setEnabled(number >= 1)            self.pushButton_load.setEnabled(True)            self.pushButton_save.setEnabled(number >= 1)if __name__ == '__main__':    import sys    from PyQt5.QtWidgets import QApplication        app = QApplication(sys.argv)    dlg = Dialog()    dlg.show()    sys.exit(app.exec_())

View Code

 

5、程序运行界面

 

 

 

标签: python, eric 6, pyqt5, gui

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
eric6+pyqt5快速开发python GUI程序
实战|教你用Python PyQt5制作一款视频数据下载小工具!
用Python定做一款小而美的计算器
打造一个window桌面应用:在线聊天对话机器人
通过继承类解决pyqt5中由qtdesigner的ui文件生成的python文件难以修改问题,方便自己添加自定义函数_python pyqtui 继承
PyQt5通信机制 信号与槽详解
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服