qtdesigner补充学习

最近编程遇到很多问题。本质上是做得多学得少导致的。所以现在打算多学习一点教程,静下心来想一想,再往下做。

第一篇教程(主要探讨关于主程序入口)

参考教程:PyQt5(designer)入门教程

编辑菜单

在这里插入图片描述

不能直接使用转存来的py代码的原因

此时尝试运行刚刚生成的“HelloWorld.py”是没用的,因为生成的文件并没有程序入口。因此我们在同一个目录下另外创建一个程序叫做“main.py”
为什么所有的教程都告诉我们要两个文件?不能放在同一个文件里吗?

ctrl+R预览

ui和逻辑(main.py)分离 因为我们已经将UI(HelloWorld.py/HelloWorld.ui)跟逻辑(main.py)分离,因此直接重复步骤7-8即可完成UI的更新,无需改动逻辑(main.py)部分。

看起来真的很不错!我应该是没有分离的。因为我如果重新画图,并不能做到直接导出就能用。那么它在main.py里实现了程序入口,也要在main.py里实现信号和槽吗?

实战 汇率转换器

为了传参,在main.py头部from functools import partial
partial的用法:partial(function,arg1,arg2,……)
它就可以给function传递arg1,agr2等参数并且运行这个函数。
这是很有用的,在之前我写的时候,虽然也可以用self.pushButton.clicked.connect(function)但因为function里没有(),自然也就不能再function里家参数。现在用partial,就可以把参数设置成ui。可是ui是什么呢?

关于这个教程中程序入口和我常用的程序入口的区别

# 创建mainWin类并传入Ui_MainWindow
class mainWin(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(mainWin, self).__init__(parent)
        self.setupUi(self)

if __name__ == '__main__':
    # 下面是使用PyQt5的固定用法
    app = QApplication(sys.argv)
    main_win = mainWin()
    main_win.show()
    sys.exit(app.exec_())

先创建一个可用类mainwin类。这个类的两个父类一个是Qmainwindow,一个是自然类。
这个可用类构造方法,一方面继承了(不知道什么父类或者是两个父类的)构造方法。我觉得应该是调用了QMainWindow的构造方法,因为Ui_MainWindow没有构造方法(…)另一方面还会完成的一件事是调用了自己的setupUi方法。这是来自Ui_MainWindow的吗?那为什么不需要super().setupUi呢?
下面这一段是主程序。参考教程:PyQt中主函数app=QApplication(sys.argv) sys.exit(app.exec_())的作用

对于任何一个使用Qt的图形用户界面应用程序,都正好存在一个QApplication对象,而不论这个应用程序在同一时间内是不是有0、1、2或更多个窗口。

在具体代码里就是app吧。
参考教程:python PyQt5.QtWidgets.QApplication类(sys.argv)(app应用对象类)

import sys
from PyQt5.QtWidgets import QApplication, QWidget

app = QApplication(sys.argv)   # 实例化一个应用对象
w = QWidget()   # 窗口界面的基本控件,它提供了基本的应用构造器。默认情况下,构造器是没有父级的,没有父级的构造器被称为窗口(window)。Dontla 20200402 啥意思,没看懂??
w.show()   # 让控件在桌面上显示出来。控件在内存里创建,之后才能在显示器上显示出来。
sys.exit(app.exec_())   # 确保主循环安全退出

和我们的基本一样,但是它没有用qtdesigner。PyQt5是一个大的模块,QtWidgets是其中的一个模块,QApplication, QWidget都是下面的类。QWidget对应在qtdesigner做法中应该是qmainwindow,都是窗口界面,功能差不多。

现在再来看一下这个教程里的程序入口长啥样。

if __name__ == '__main__':
    app = QApplication(sys.argv)
    MainWindow = QMainWindow()
    ui = gui_file_name.Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

我突然觉得挺像的。都是先用QMainWindow的构造方法构造一个标准化窗口,然后用ui_mainwindow的setup方法来setup这个标准化窗口使之具有相应的布局等。

补充1:python子类的构造函数

单继承

若子类不重写__init__,则会自动调用父类的__init__
init(self,arg1,arg2),那么在类的实例化过程中,我们就会这样写:father=Father(arg1,arg2)

class Father(object):
    def __init__(self, name):
        self.name=name
        print ( "name: %s" %( self.name) )
    def getName(self):
        return 'Father ' + self.name
 
class Son(Father):
    def getName(self):
        return 'Son '+self.name
 
if __name__=='__main__':
    son=Son('runoob')
    print ( son.getName() )

子类也可以完全重写__init__方法

class Father(object):
    def __init__(self, name):
        self.name=name
        print ( "name: %s" %( self.name) )
    def getName(self):
        return 'Father ' + self.name
 
class Son(Father):
    def __init__(self, name):
        print ( "hi" )
        self.name =  name
    def getName(self):
        return 'Son '+self.name
 
if __name__=='__main__':
    son=Son('runoob')
    print ( son.getName() )

如果重写时要继承父类的__init__方法:

super(子类,self).__init__(参数1,参数2....)
父类名称.__init__(self,参数1,参数2...)

这里的参数是不是至少应该包括父类的构造方法中的全部参数,可以增加,不能减少?

例如:

class Father(object):
    def __init__(self, name):
        self.name=name
        print ( "name: %s" %( self.name))
    def getName(self):
        return 'Father ' + self.name
 
class Son(Father):
    def __init__(self, name):
        super(Son, self).__init__(name)
        print ("hi")
        self.name =  name
    def getName(self):
        return 'Son '+self.name
 
if __name__=='__main__':
    son=Son('runoob')
    print ( son.getName() )

son的构造函数里可不可以把self.name = name去掉?因为父类的构造函数里已经有这句话了。

多继承

参考教程:python中单继承和多继承中子类默认继承父类的哪个构造函数__init__
(1)子类继承于多个父类,并且子类无__init__时,则按继承顺序,哪个父类在最前面且有自己的__init__,则继承它;若最前面的父类无__init__,则继承第二个父类的__init__,若还是无__init__,则依次往后寻找,直到继承的某个父类含__init__
子类继承于多个父类,并且子类含__init__时,和单继承的(2)类似,不会自动调用所有父类__init__,如需使用某个父类__init__中的变量,则需要在子类__init__中显式调用,此处不再赘述

可是这两种情况不是子类直接继承就是子类直接重写,有没有继承并且改写?是不是默认改写第一个?

参考教程:python 多重类继承__init__
super.父类函数(arg……)就可以在子类中调用父类的函数

class A:
    def __init__(self):
        self.x = 0

class B(A):
    def __init__(self):
        super().__init__()
        self.y = 1

上面这段代码就是用super().调用了父类的构造函数。

第二篇教程(designer的各种功能)

基于QTdesigner的PyQt编程

用qtdesigner的时候最好在制作完界面后对界面进行布局。在布局中你可以多运用Horizontal Spacer 和vertical spacer。一般我会一行一行进行水平布局之后再整体进行垂直布局。

#首先你需要在引用的python文件内导入该对象所在的文件,也就是main_menu.py
import main_menu   #导入该对象所在文件
Ui_MainWindow = main_menu.Ui_MainWindow#指定Ui_MainWindow 为main_menu文件下的Ui_MainWindow对象。

class CoperQt(QtWidgets.QMainWindow,Ui_MainWindow):#创建一个Qt对象
#这里的第一个变量是你该窗口的类型,第二个是该窗口对象。
#这里是主窗口类型。所以设置成当QtWidgets.QMainWindow。
#你的窗口是一个会话框时你需要设置成:QtWidgets.QDialog
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)  # 创建主界面对象
        Ui_MainWindow.__init__(self)#主界面对象初始化
        self.setupUi(self)  #配置主界面对象

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = CoperQt()#创建QT对象
    window.show()#QT对象显示
    sys.exit(app.exec_())

这段代码告诉我们:
QtWidgets.QMainWindow是主窗口类型,所以如果主窗口类型是对话框,还要改成QtWidgets.QDialog。

 QtWidgets.QMainWindow.__init__(self)  
 Ui_MainWindow.__init__(self)

这两句话居然放在了创建类里,所以这两句话和super(mainWin, self).__init__(parent)这一句话是一个功能。
这一整个类是一个Qt对象。

按钮
self.Button0.clicked.connect(self.start_find)  # button0的点击事件绑定start_find函数
关于绑定函数的传参除了可以使用全局变量还可以使用python的lambda,如我要传入x:
self.Button0.clicked.connect(command=lambda:button_process(x))

虽然我也不知道参数是怎么来的,但是也可以用
partial。
这篇文章里还讲了定时器。
ctrl+R可以实现窗口的预览。

下拉选项栏comboBox

选项栏有两个标识,一个是每一栏的编号index(从0开始),一个是每一栏的文本内容text:

  self.comboBox.insertItem(0, self.tr("None"))  # 第一个选项插入空
    self.comboBox.insertItem(0, "x") 第一个选项插入x字符
    self.comboBox.currentText() 读取选项栏文本:
   # self.comboBox.currentIndex() 读取选项栏编号:
   # self.comboBox.setCurrentIndex() 设置当前选项栏显示位置:(通过编号)
    #self.comboBox.setCurrentText() 设置当前选项栏显示位置:(通过文本)
    #self.comboBox.clear() 清空当前选项框内元素

如何让选项栏选中后不用按按钮就触发事件。实际上就是运用到上面的定时器,你可以将定时器绑定上选项栏读取函数,这个函数每隔200MS或者1s读取选项栏的数值,这样,用户的只要更换选项立马能够做出反映。

单选框radioButton
self.radioButton.clicked.connect(self.change_radio)  # 单选按钮选中绑定函数
self.radioButton.hide()  # 单选框2隐藏
self.radioButton.setChecked(True)#单选框选中,反之False
self.radioButton.isChecked()   #单选框是否选中,选中返回True反之False
复选框checkBox

可以右键单选框得到。区别是可以都选可以都不选。

文本框lineEdit
输入框.png
self.lineEdit.returnPressed.connect(self.check_info)  # 文本栏回车绑定函数
self.lineEdit.setEchoMode(QtWidgets.QLineEdit.Password)#设置成密码模式,也就是输入内容显示为实心的圆
self.lineEdit.setEchoMode(QtWidgets.QLineEdit.Normal)#设置成普通模式(默认)
self.lineEdit.setText(“hello world”)      # 设置输入文本
self.lineEdit.text()#返回输入框文本内容
self.lineEdit.show()#显示文本框
self.lineEdit.hide()#隐藏文本框
self.lineEdit.clear()#清空文本框

第三篇教程 关于页面设计和布局

参考教程:
PyQT5 之 Qt Designer 介绍与入门

第四篇教程 一个分离了逻辑和页面设计的例子

参考教程:PyQt5+Qt designer实战
clat.py原封不动地保存,另建run.py


class mwindow(QWidget, Ui_Form):
    def __init__(self):
        super(mwindow, self).__init__()
        self.setupUi(self)
 
    def ps_bt(self):
        self.textBrowser.clear()

原本的话应该只有上面这一段构造函数,但是现在,除了构造函数之外,还有很多新的函数。

class mwindow(QWidget, Ui_Form):
    def __init__(self):
        super(mwindow, self).__init__()
        self.setupUi(self)
 
    def ps_bt(self):
        self.textBrowser.clear()
 
    def ps_bt1(self):
        self.lineEdit.insert('/')
 
    def ps_bt2(self):
        self.lineEdit.insert('*')
 
    def ps_bt3(self):
        self.lineEdit.insert('+')
 
    def ps_bt4(self):
        self.lineEdit.insert('-')
 
    def ps_bt5(self):
        self.lineEdit.insert('=')
        self.calculate()
 
    def ps_bt6(self):
        self.lineEdit.insert('.')
 
    def ps_bt7(self):
        self.lineEdit.insert('0')
 
    def ps_bt8(self):
        self.lineEdit.insert('1')
 
    def ps_bt9(self):
        self.lineEdit.insert('2')
 
    def ps_bt10(self):
        self.lineEdit.insert('3')
 
    def ps_bt11(self):
        self.lineEdit.insert('4')
 
    def ps_bt12(self):
        self.lineEdit.insert('5')
 
    def ps_bt13(self):
        self.lineEdit.insert('6')
 
    def ps_bt14(self):
        self.lineEdit.insert('7')
 
    def ps_bt15(self):
        self.lineEdit.insert('8')
 
    def ps_bt16(self):
        self.lineEdit.insert('9')
 
    def ps_bt17(self):
        self.lineEdit.backspace()
 
    def ps_bt18(self):
        self.lineEdit.clear()
 
    def ps_bt19(self):
        self.close()
 
    def lineEdit_clear(self):
        self.lineEdit.clear()
 
    def calculate(self):
        # text = self.lineEdit.text()
        # self.lineEdit.setText('%s= %.2f' % (text, eval(text)))
        text = self.lineEdit.text()
        self.textBrowser.append('%s= %.2f' % (text, eval(text)))

总的来说,在这个可用类的定义中,有构造函数和各种槽函数,但是没有写触发条件。

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = mwindow()
    w.pushButton.clicked.connect(w.ps_bt)
    w.pushButton_1.clicked.connect(w.ps_bt1)
    w.pushButton_2.clicked.connect(w.ps_bt2)
    w.pushButton_3.clicked.connect(w.ps_bt3)
    w.pushButton_4.clicked.connect(w.ps_bt4)
    w.pushButton_5.clicked.connect(w.calculate)
    w.pushButton_6.clicked.connect(w.ps_bt6)
    w.pushButton_7.clicked.connect(w.ps_bt7)
    w.pushButton_8.clicked.connect(w.ps_bt8)
    w.pushButton_9.clicked.connect(w.ps_bt9)
    w.pushButton_10.clicked.connect(w.ps_bt10)
    w.pushButton_11.clicked.connect(w.ps_bt11)
    w.pushButton_12.clicked.connect(w.ps_bt12)
    w.pushButton_13.clicked.connect(w.ps_bt13)
    w.pushButton_14.clicked.connect(w.ps_bt14)
    w.pushButton_15.clicked.connect(w.ps_bt15)
    w.pushButton_16.clicked.connect(w.ps_bt16)
    w.pushButton_17.clicked.connect(w.ps_bt17)
    w.pushButton_18.clicked.connect(w.ps_bt18)
    w.pushButton_19.clicked.connect(w.ps_bt19)
    w.show()
    sys.exit(app.exec_())

主函数。这个例子告诉我们,即使一个页面已经实例化了,它也可以再将元件的信号和槽连接在一起。就以普通的代码呈现,而不一定要在自然类的setup方法里。
另外如果想加入界面背景:

    def resizeEvent(self, event):
        palette = QPalette()
        pix = QPixmap('resources/background.jpg')
        pix = pix.scaled(self.width(), self.height())
        palette.setBrush(QPalette.Background, QBrush(pix))
        self.setPalette(palette)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Qt是一款跨平台的C++应用程序开发框架,可以用于制作各种类型的应用软件,包括网口抓包软件。 要使用Qt制作网口抓包软件,首先我们需要了解一些基础知识。网口抓包是指通过监听网络接口,获取传输过程中的网络数据包。在Qt中,我们可以使用Qt网络模块来实现这个功能。 Qt网络模块提供了一些类和函数,可以对网络操作进行管理和控制。通过使用这些类和函数,我们可以轻松地实现网口抓包功能。具体步骤如下: 1. 创建一个Qt应用程序,并导入Qt网络模块。 2. 使用Qt网络模块提供的类和函数,创建一个网络套接字。 3. 设置套接字的相关参数,如IP地址和端口。 4. 监听套接字,开始捕获网络数据包。 5. 解析捕获到的数据包,提取有用的信息。 6. 将提取的信息显示在用户界面上,或者保存到文件中。 通过以上步骤,我们就可以实现一个简单的网口抓包软件。当然,根据实际需求,我们还可以进行更多的功能扩展,比如添加过滤器、支持多线程等。 Qt的跨平台特性也使得我们可以将这个网口抓包软件移植到不同的操作系统上,如Windows、Linux和MacOS等。 总之,Qt作为一款强大的C++开发框架,能够很好地支持制作网口抓包软件。我们只需要利用Qt提供的网络模块,加上一些基本的编程技巧,就能够实现一个功能强大、界面友好的网口抓包软件。 ### 回答2: Qt是一种跨平台的C++ GUI框架,可以用于开发各种类型的应用程序,包括网络抓包软件。下面我将使用中文解答如何使用Qt来制作网口抓包软件。 首先,我们需要使用Qt编写一个简单的图形界面,用于显示捕获的网络数据包和用户交互。可以使用Qt的Widget或QML来设计界面,添加按钮、表格和文本框等控件。 然后,我们需要使用Qt的网络库来实现对网口的捕获和处理。Qt的网络库提供了一些类和函数,用于创建和管理网络连接。我们可以使用QUdpSocket或QTcpSocket类来监听和接收网络数据包。可以设置套接字的属性和选项,以满足不同的需求。 在数据包捕获过程中,我们可以使用Qt提供的类和函数来解析和分析数据包。例如,可以使用QByteArray类来读取和处理原始数据。可以使用QNetworkDatagram或QNetworkPacket类来封装和处理网络数据包。 为了更好地展示和分析捕获的数据包,我们可以使用Qt的绘图和图表功能。通过使用QPainter、QPaintDevice或QChart等类,我们可以将数据包的相关信息以图表、图像或其他形式展示给用户。 最后,我们可以使用Qt的文件处理类和函数来保存和加载捕获的数据包。可以使用QFile类来读写数据文件,并使用QDataStream类来序列化和反序列化数据。 总的来说,Qt提供了丰富的功能和工具来开发网口抓包软件。通过合理选择和组合Qt的类和函数,我们可以实现一个功能强大、易于使用的网络抓包工具。当然,在开发过程中,我们还需要具备一定的网络编程和数据处理知识,以及对Qt框架的熟悉和理解。 ### 回答3: Qt(即C++开发框架)是一种用于创建跨平台应用程序的工具。要制作一个网口抓包软件,可以使用Qt来实现。下面是一些关键步骤: 1. 建立Qt项目:首先,在Qt开发环境中创建一个新的项目。选择适当的项目类型,例如Console Application或Widget Application。 2. 设计用户界面:使用Qt的图形用户界面设计工具,如Qt Designer,创建一个符合需求的界面。可以添加按钮、文本框和其他交互元素来控制抓包功能,并在显示捕获数据的区域添加一个文本框或列表。 3. 添加网络库和相关功能:使用Qt的网络模块,如Qt Network,将网络通信功能添加到项目中。这样就可以在软件中进行网络抓包。 4. 捕获网络数据:使用Qt提供的相关函数,在应用程序中打开并监听网络接口。可以使用Qt的信号和槽机制来监控网络数据流量,并将捕获的数据显示在界面上。 5. 对数据进行处理和解析:根据需求,可以使用C++的网络编程API或自定义的网络协议解析库来处理捕获的网络数据。这可能包括解析数据包头、提取特定字段等。 6. 实现过滤和分析功能:如果需要,可以增加过滤和分析捕获数据的功能。例如,可以根据源/目的IP地址、端口号或协议类型对数据包进行过滤,并显示符合条件的数据。 7. 添加保存和导出功能:可以让用户将捕获的数据保存到本地文件,并提供导出文件的选项。可以使用Qt提供的文件处理函数进行文件操作。 8. 测试和调试:在开发过程中,进行严格的测试和调试,确保软件的稳定性和正确性。可以使用Qt的调试工具、日志输出和单元测试框架等。 9. 打包和分发:完成开发后,将软件打包成可执行文件或安装程序。根据目标平台,使用Qt的相关工具来打包和分发软件。 通过以上步骤,可以使用Qt开发一个功能完善、易于使用的网口抓包软件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值