跳转到内容
主菜单
主菜单
移至侧栏
隐藏
规范/协议
协议
算法
JVM
多线程/并发
存储
AI
深度学习
工具箱
最近更改
文章分类
全部文章
WHY42
搜索
搜索
外观
登录
个人工具
登录
欢迎来到Riguz的小站!这是一个私人wiki,用来记录一些我的笔记。
查看“︁PyQt5 hello world”︁的源代码
页面
讨论
大陆简体
阅读
查看源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
查看源代码
查看历史
常规
链入页面
相关更改
页面信息
外观
移至侧栏
隐藏
←
PyQt5 hello world
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
{{DISPLAYTITLE:PyQt5入门小程序}} 最近有非计算机专业的同学想学PyQT,但是又不知道怎么搞,所以我做了一个简单的例子。这个例子是一个简单的图片显示器。这是一篇写给新人的入门文章,希望有所帮助。 = Qt程序的基本结构= 跟其他程序一样,所有的程序都会有一个主入口,然后一行一行的调用代码,而GUI程序跟其他程序有一个区别就是,只有你显示的关闭界面,程序才会退出。所以整个GUI的程序大致会是这样一个原理(下面是伪代码,不是实际的程序): <syntaxhighlight lang="java"> void main() { while(true) { command = fetch_user_input_event() if(command == quit): exit(); else keep_rendering_ui } } </syntaxhighlight> 然而实际上不需要我们去操心这个,Qt框架会帮我们处理这个逻辑,一个Qt应用就是这样: <syntaxhighlight lang="python"> def main(): app = QApplication(sys.argv) window = MainWindow() window.show() # 必须显示的调用,显示一个界面 app.exec_() # 等待程序退出,否则界面一闪而过 if __name__ == '__main__': main() </syntaxhighlight> = UI绘制= UI绘制十分简单,我们的程序最终的样子是这样: [[File:PyQt_image_viewer.png|600px|Image viewer]] 一个比较典型的桌面程序,一个主界面包含菜单栏、工具栏、主界面,状态栏没有。这些都好理解,而另一个比较重要的概念是布局,就是控件在UI上怎么摆放(尤其是UI可能会缩放),通常不会是写死的位置,而是由布局管理器来管理。简而言之,就是定义规则,你的控件怎么放,窗口缩放的时候,怎么处理。 == 主窗口== 所以首先我们定义出主窗口。 <syntaxhighlight lang="python"> class MainWindow(QMainWindow): def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) self.setWindowTitle('Simple image editor') self.setFixedSize(640, 480) # 固定大小的窗口,禁止缩放 </syntaxhighlight> 实际上你可以直接显示一个其他控件例如QWidget, QLabel等,它们只是控件级别,而主窗口包含菜单、状态栏等,更适合制作程序UI。然后我们主界面的控件只有一个,那就是显示图片。图片可以使用QLabel显示,虽然它更多用来显示文字: <syntaxhighlight lang="python"> # 在Qt里面,每一个控件都可以指定父控件,更多的是因为C++中需要自动管理内存 # 当父控件销毁时,子控件跟着销毁,所以把self(主窗口)传给主窗口上的控件 self.imageContainer = QLabel(self) self.imageContainer.setAlignment(Qt.AlignCenter) # qt可以写css来设置样式 self.imageContainer.setStyleSheet('background-image:url(background.jpg);') # 将图片设置为中心控件 self.setCentralWidget(self.imageContainer) </syntaxhighlight> == 创建菜单和工具栏== 菜单通过`self.menuBar`得到。 <syntaxhighlight lang="python"> menu = self.menuBar() # 是否使用系统菜单,如果是mac,不设置的话菜单会在屏幕顶上 menu.setNativeMenuBar(False) aboutMenu = menu.addMenu('&关于') aboutMenu.addAction(aboutAction) </syntaxhighlight> 工具栏跟菜单很类似,工具栏上的按钮都是一个Action,如果希望放进去别的控件可以用`addWidget`实现 <syntaxhighlight lang="python"> # 创建一个新的工具栏,可以创建多个 self.toolbar = self.addToolBar('Operations') # 图标按钮 zoomInAction = QAction(QIcon('zengjia.svg'), '放大', self) self.toolbar.addAction(zoomInAction) # 非按钮控件 slider = QSlider(Qt.Horizontal) slider.setFixedWidth(200) self.toolbar.addWidget(slider) </syntaxhighlight> = 事件响应= Qt是信号(Signal)/槽(Slot)机制,简单来说就是用户对界面的更改会产生事件,而事件由槽来处理,两者之间需要关联(connect)上才能正确处理。比如菜单的处理: <syntaxhighlight lang="python"> aboutAction = QAction('&版本', self) aboutAction.setShortcut('Ctrl+A') # triggered事件 关联到槽,槽就是一个函数 aboutAction.triggered.connect(self.onAbout) </syntaxhighlight> 有时候事件是会有参数的,比如滑块变化的时候,值是可以得到的: <syntaxhighlight lang="python"> slider = QSlider(Qt.Horizontal) slider.setFixedWidth(200) slider.setValue(100) slider.valueChanged.connect(self.onChangeBrightness) # 槽 def onChangeBrightness(self, value): # 这个value就是变化后的值(默认0-100) pass </syntaxhighlight> = 图片处理= == 放大缩小== 方法和缩小通过QPixmap.scaled来实现,我们通过将图片缩放到一个期望的大小(保持宽高比),来显示到界面上: <syntaxhighlight lang="python"> scaledImage = rotatedImage.scaled(self.imageSize.width(), self.imageSize.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation) self.imageContainer.setPixmap(scaledImage) </syntaxhighlight> 而缩放的时候,实际上就是在控制这个大小: <syntaxhighlight lang="python"> # 一开始给定一个默认的大小 self.imageSize = QSize(300, 200) def onZoomOut(self): # 缩小按0.5计算,扩大按照乘以1.5计算 self.imageSize *= 0.5 self.refreshImage() </syntaxhighlight> == 旋转== 旋转需要记录一个旋转角度,然后通过Qtransform来实现: <syntaxhighlight lang="python"> transform = QTransform() transform.rotate(self.rotateAngle) rotatedImage = self.image.transformed(transform) </syntaxhighlight> 这样可以得到一个新的QPixmap,就是旋转后的图片。 == 调节亮度== 亮度调节就比较麻烦了,图片的亮度调节需要在HSL的颜色空间下处理(我们比较熟悉的一帮是RGB三色表示)。 <syntaxhighlight lang="python"> # 将QPixmap转为QImage,以便可以直接操作像素 image = self.rawImage.toImage() for i in range(0, image.width()): for j in range(0, image.height()): # 取到(i, j)位置的像素点 color = QColor(image.pixelColor(i, j)) # 取到HSL空间下的像素值 (h, s, l, a) = color.getHsl() # 计算调整后的亮度值并更新,更新的时候转成了rgb newBrightless = l * (value/100.0) color.setHsl(h, s, newBrightless, a) image.setPixel(i, j, color.rgb()) self.image = QPixmap.fromImage(image) </syntaxhighlight> 以上就是一个简单的例子,完整的程序[/images/ImageEditor.zip 下载]:
返回
PyQt5 hello world
。
搜索
搜索
查看“︁PyQt5 hello world”︁的源代码
添加话题