21.md 13.8 KB
Newer Older
W
init  
wizardforcel 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
# PyQt5 中的第一个程序

> 原文: [http://zetcode.com/gui/pyqt5/firstprograms/](http://zetcode.com/gui/pyqt5/firstprograms/)

在 PyQt5 教程的这一部分中,我们学习一些基本功能。 这些示例显示了一个工具提示和一个图标,关闭了一个窗口,显示了一个消息框,并在桌面上将窗口居中。

## 简单的例子

这是一个显示小窗口的简单示例。 然而,我们可以利用这个窗口做很多事情。 我们可以调整大小,最大化或最小化它。 这需要大量的编码。 已经有人对该功能进行了编码。 由于它在大多数应用程序中都重复执行,因此无需再次编码。 PyQt5 是高级工具包。 如果我们使用较低级的工具箱进行编码,则下面的代码示例可能很容易包含数百行。

`simple.py`

```
#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial 

In this example, we create a simple
window in PyQt5.

Author: Jan Bodnar
Website: zetcode.com 
Last edited: August 2017
"""

import sys
from PyQt5.QtWidgets import QApplication, QWidget

if __name__ == '__main__':

    app = QApplication(sys.argv)

    w = QWidget()
    w.resize(250, 150)
    w.move(300, 300)
    w.setWindowTitle('Simple')
    w.show()

    sys.exit(app.exec_())

```

上面的代码示例在屏幕上显示了一个小窗口。

```
import sys
from PyQt5.QtWidgets import QApplication, QWidget

```

在这里,我们提供必要的进口。 基本窗口小部件位于`PyQt5.QtWidgets`模块中。

```
app = QApplication(sys.argv)

```

每个 PyQt5 应用程序都必须创建一个应用程序对象。 `sys.argv`参数是命令行中的参数列表。 可以从外壳运行 Python 脚本。 这是我们可以控制脚本启动的方式。

```
w = QWidget()

```

`QWidget`小部件是 PyQt5 中所有用户界面对象的基类。 我们为`QWidget`提供了默认的构造函数。 默认构造函数没有父代。 没有父级的窗口小部件称为窗口。

```
w.resize(250, 150)

```

`resize()`方法调整窗口小部件的大小。 宽 250 像素,高 150 像素。

```
w.move(300, 300)

```

`move()`方法将窗口小部件移动到屏幕上 x = 300,y = 300 坐标的位置。

```
w.setWindowTitle('Simple')

```

我们用`setWindowTitle()`设置窗口的标题。 标题显示在标题栏中。

```
w.show()

```

`show()`方法在屏幕上显示小部件。 首先在内存中创建一个小部件,然后将其显示在屏幕上。

```
sys.exit(app.exec_())

```

最后,我们进入应用程序的主循环。 事件处理从这一点开始。 mainloop 从窗口系统接收事件,并将其分配给应用程序小部件。 如果调用`exit()`方法或主窗口小部件被销毁,则主循环结束。 `sys.exit()`方法可确保干净退出。 将告知环境应用程序如何结束。

`exec_()`方法带有下划线。 这是因为`exec`是 Python 关键字。 因此,使用了`exec_()`

![Simple](img/0a65d25d0b0e047b0706e7505851f171.jpg)

Figure: Simple

## 应用程序图标

应用程序图标是一个小图像,通常显示在标题栏的左上角。 在下面的示例中,我们将展示如何在 PyQt5 中做到这一点。 我们还将介绍一些新方法。

某些环境在标题栏中不显示图标。 我们需要启用它们。 如果没有看到图标,请参阅我在 Stackoverflow 上的[答案](https://stackoverflow.com/questions/44080247/pyqt5-does-now-show-icons/45439678#45439678)以获取解决方案。

`icon.py`

```
#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial 

This example shows an icon
in the titlebar of the window.

Author: Jan Bodnar
Website: zetcode.com 
Last edited: August 2017
"""

import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QIcon

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):

        self.setGeometry(300, 300, 300, 220)
        self.setWindowTitle('Icon')
        self.setWindowIcon(QIcon('web.png'))        

        self.show()

if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

```

前面的示例以过程样式编码。 Python 编程语言支持过程和面向对象的编程风格。 在 PyQt5 中编程意味着在 OOP 中编程。

```
class Example(QWidget):

    def __init__(self):
        super().__init__()
        ...

```

面向对象编程中的三个重要方面是类,数据和方法。 在这里,我们创建了一个名为`Example`的新类。 `Example`类继承自`QWidget`类。 这意味着我们调用了两个构造函数:第一个构造函数用于`Example`类,第二个构造函数用于继承的类。 `super()`方法返回`Example`类的父对象,我们将其称为构造函数。 `__init__()`方法是 Python 语言的构造方法。

```
self.initUI() 

```

GUI 的创建委托给`initUI()`方法。

```
self.setGeometry(300, 300, 300, 220)
self.setWindowTitle('Icon')
self.setWindowIcon(QIcon('web.png'))  

```

所有这三种方法都从`QWidget`类继承。 `setGeometry()`做两件事:在屏幕上找到窗口并设置其大小。 前两个参数是窗口的 x 和 y 位置。 第三个是窗口的宽度,第四个是窗口的高度。 实际上,它将`resize()``move()`方法结合在一起。 最后一种方法设置应用程序图标。 为此,我们创建了一个`QIcon`对象。 `QIcon`接收到要显示的图标的路径。

```
if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())  

```

将创建应用程序和示例对象。 主循环开始。

![Icon](img/fde5558ff960d66134deda62f76234cc.jpg)

Figure: Icon

## 显示工具提示

我们可以为我们的任何小部件提供气球帮助。

`tooltip.py`

```
#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial 

This example shows a tooltip on 
a window and a button.

Author: Jan Bodnar
Website: zetcode.com 
Last edited: August 2017
"""

import sys
from PyQt5.QtWidgets import (QWidget, QToolTip, 
    QPushButton, QApplication)
from PyQt5.QtGui import QFont    

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):

        QToolTip.setFont(QFont('SansSerif', 10))

        self.setToolTip('This is a <b>QWidget</b> widget')

        btn = QPushButton('Button', self)
        btn.setToolTip('This is a <b>QPushButton</b> widget')
        btn.resize(btn.sizeHint())
        btn.move(50, 50)       

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('Tooltips')    
        self.show()

if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

```

在此示例中,我们显示了两个 PyQt5 小部件的工具提示。

```
QToolTip.setFont(QFont('SansSerif', 10))

```

此静态方法设置用于呈现工具提示的字体。 我们使用 10pt SansSerif 字体。

```
self.setToolTip('This is a <b>QWidget</b> widget')

```

要创建工具提示,我们调用`setTooltip()`方法。 我们可以使用富文本格式。

```
btn = QPushButton('Button', self)
btn.setToolTip('This is a <b>QPushButton</b> widget')

```

我们创建一个按钮小部件并为其设置工具提示。

```
btn.resize(btn.sizeHint())
btn.move(50, 50)       

```

调整按钮的大小并在窗口上移动。 `sizeHint()`方法为按钮提供了建议的尺寸。

![Tooltips](img/f35a00e3fce080f01b141b313e41900b.jpg)

Figure: Tooltips

W
wizardforcel 已提交
296
## 关闭窗口
W
init  
wizardforcel 已提交
297

W
wizardforcel 已提交
298
关闭窗口的明显方法是单击标题栏上的 x 标记。 在下一个示例中,我们展示了如何以编程方式关闭窗口。 我们将简要介绍信号和槽。
W
init  
wizardforcel 已提交
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369

以下是我们在示例中使用的`QPushButton`小部件的构造函数。

```
QPushButton(string text, QWidget parent = None)

```

`text`参数是将在按钮上显示的文本。 `parent`是一个小部件,我们在其上放置了按钮。 在我们的情况下,它将是`QWidget`。 应用程序的小部件形成层次结构。 在此层次结构中,大多数小部件都有其父级。 没有父母的小部件是顶层窗口。

`quitbutton.py`

```
#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial 

This program creates a quit
button. When we press the button,
the application terminates. 

Author: Jan Bodnar
Website: zetcode.com 
Last edited: January 2018
"""

import sys
from PyQt5.QtWidgets import QWidget, QPushButton, QApplication

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):               

        qbtn = QPushButton('Quit', self)
        qbtn.clicked.connect(QApplication.instance().quit)
        qbtn.resize(qbtn.sizeHint())
        qbtn.move(50, 50)       

        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Quit button')    
        self.show()

if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

```

在此示例中,我们创建一个退出按钮。 单击按钮后,应用程序终止。

```
qbtn = QPushButton('Quit', self)

```

我们创建一个按钮。 该按钮是`QPushButton`类的实例。 构造函数的第一个参数是按钮的标签。 第二个参数是父窗口小部件。 父窗口小部件是`Example`小部件,通过继承它是`QWidget`

```
qbtn.clicked.connect(QApplication.instance().quit)

```

W
wizardforcel 已提交
370
PyQt5 中的事件处理系统是通过信号&槽机制构建的。 如果单击按钮,将发出信号`clicked`。 该槽可以是 Qt 槽或任何可调用的 Python。
W
init  
wizardforcel 已提交
371 372 373 374 375 376 377

`QApplication.instance()`检索的`QCoreApplication`包含主事件循环-它处理并调度所有事件。 单击的信号连接到`quit()`方法,该方法终止应用程序。 通信是在两个对象之间进行的:发送者和接收者。 发送者是按钮,接收者是应用程序对象。

![Quit button](img/1aace4fa77667a78135228a42f1d48e3.jpg)

Figure: Quit button

W
wizardforcel 已提交
378
## 消息框
W
init  
wizardforcel 已提交
379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551

默认情况下,如果单击标题栏上的 x 按钮,则`QWidget`将关闭。 有时我们想要修改此默认行为。 例如,如果我们在编辑器中打开了一个文件,对此我们做了一些更改。 我们显示一个消息框以确认操作。

`messagebox.py`

```
#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial 

This program shows a confirmation 
message box when we click on the close
button of the application window. 

Author: Jan Bodnar
Website: zetcode.com 
Last edited: August 2017
"""

import sys
from PyQt5.QtWidgets import QWidget, QMessageBox, QApplication

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):               

        self.setGeometry(300, 300, 250, 150)        
        self.setWindowTitle('Message box')    
        self.show()

    def closeEvent(self, event):

        reply = QMessageBox.question(self, 'Message',
            "Are you sure to quit?", QMessageBox.Yes | 
            QMessageBox.No, QMessageBox.No)

        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()        

if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

```

如果我们关闭`QWidget`,则会生成`QCloseEvent`。 要修改小部件的行为,我们需要重新实现`closeEvent()`事件处理程序。

```
reply = QMessageBox.question(self, 'Message',
    "Are you sure to quit?", QMessageBox.Yes | 
    QMessageBox.No, QMessageBox.No)

```

我们显示一个带有两个按钮的消息框:是和否。第一个字符串出现在标题栏上。 第二个字符串是对话框显示的消息文本。 第三个参数指定出现在对话框中的按钮的组合。 最后一个参数是默认按钮。 该按钮最初具有键盘焦点。 返回值存储在`reply`变量中。

```
if reply == QtGui.QMessageBox.Yes:
    event.accept()
else:
    event.ignore()  

```

在这里,我们测试返回值。 如果单击“是”按钮,我们将接受导致小部件关闭和应用程序终止的事件。 否则,我们将忽略关闭事件。

![Message box](img/2103dacd426f497b2bc5075009127ef9.jpg)

Figure: Message box

## 屏幕上的居中窗口

以下脚本显示了如何在桌面屏幕上居中放置窗口。

`center.py`

```
#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial 

This program centers a window 
on the screen. 

Author: Jan Bodnar
Website: zetcode.com 
Last edited: August 2017
"""

import sys
from PyQt5.QtWidgets import QWidget, QDesktopWidget, QApplication

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):               

        self.resize(250, 150)
        self.center()

        self.setWindowTitle('Center')    
        self.show()

    def center(self):

        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

```

`QDesktopWidget`类提供有关用户桌面的信息,包括屏幕尺寸。

```
self.center()

```

将使窗口居中的代码位于自定义`center()`方法中。

```
qr = self.frameGeometry()

```

我们得到一个指定主窗口几何形状的矩形。 这包括任何窗框。

```
cp = QDesktopWidget().availableGeometry().center()

```

我们计算出显示器的屏幕分辨率。 从这个分辨率,我们得到了中心点。

```
qr.moveCenter(cp)

```

我们的矩形已经具有宽度和高度。 现在,我们将矩形的中心设置为屏幕的中心。 矩形的大小不变。

```
self.move(qr.topLeft())

```

我们将应用程序窗口的左上角移动到 qr 矩形的左上角,从而将窗口居中放置在屏幕上。

在 PyQt5 教程的这一部分中,我们在 PyQt5 中创建了简单的代码示例。