' ~$ a# c7 u0 e, E& {8 g# Gqt5-tools 5.15.2.1.2 has requirement click~=7.0, but you'll have click 8.0.1 which is incompatible.3 ^' |: q0 H: t% p- U, Q
解决方案: 6 Y0 q( m9 ^) m7 O L! }" Z/ x1 c' p3 k" F
pip install click~=7.0 . \9 r1 D3 E' p- Y! Z! z. P( NQt Designer的配置 / R- {, a2 t! K/ O" T/ |* _/ m0 t
Qt Designer 是通过拖拽的方式放置控件,并实时查看控件效果进行快速UI设计。) [% ~7 E8 O9 _3 H- s
7 s- ~; ~6 g+ F
% @- C" I2 v4 O
0 h/ r) l6 _$ |/ f
整个画面的构成: ) R* [9 d' g' b+ ^) S - c5 i) }! @$ o9 C6 K左侧的“Widget Box”就是各种可以自由拖动的组件 H4 R% D6 I9 b5 x+ W' m: F; Y3 X 1 P& d" z; p8 U H中间的“MainWindow – untitled”窗体就是画布 4 Y# E* F% H7 o ^, ~$ ?6 D$ R; y9 j) P/ ], E0 B
右上方的”Object Inspector”可以查看当前ui的结构" o' `$ l" Q0 Z% D
! T% \+ D1 g* }2 Z4 d! `6 ]
右侧中部的”Property Editor”可以设置当前选中组件的属性 # U5 p1 {' ]! B9 L5 ` F, W( _# |3 f- }3 \; [右下方的”Resource Browser”可以添加各种素材,比如图片,背景等等 ' i6 t/ z4 a3 S8 g% A- V x2 N- G2 X% x+ q最终生成.ui文件(实质上是XML格式的文件),可直接使用,也可以通过pyuic5工具转换成.py文件。 ! ^8 w l3 v( Z5 [; y5 `$ j 7 l* _0 ?) A: a& ]3 `QtDisigner配置 4 N3 d& s4 m. J5 o" [ & d, O$ v6 \4 i' t! ^! y& y在Pycharm中,依次打开 File – Settings – Tools – External Tools,点击 + Create Tool,配置如下: $ v8 O2 a X2 q# A+ c7 m% h1 l* u* L5 u# ~
Name: QtDisigner 8 c2 O( J7 b* L4 A3 G! l% n: ?+ h4 P+ V3 J' B0 Y. B3 w: d
Program : D:\Program Files\Python36\Lib\site-packages\qt5_applications\Qt\bin\designer.exe # 请根据实际修改6 ]4 v4 C( T" d7 g! @7 W
/ b; i7 z, ~1 YWorking directory: $FileDir$8 l1 V% c8 y7 T S9 p
PyUIC配置! A6 j8 T+ a$ U% W
( C' Y/ X" @$ l3 C
PyUIC主要是把Qt Designer生成的.ui文件换成.py文件。: ?* O, q& o8 k6 `
) l' m/ ]8 g) J! H$ j4 x7 i( D3 ?
在Pycharm中,依次打开 File – Settings – Tools – External Tools,点击 + Create Tool,配置如下:; b0 m8 V- h" \+ j
6 b, L% N3 f' f0 pName: PyUIC5 w" m) A2 J8 E- g( E
# e; Y9 w a8 T) F+ ]5 t. ~
Program : D:\Program Files\Python36\python.exe # 当前Python目录,请根据实际修改% B2 S+ s1 O$ B3 c, b
* r; K: X+ g% IArguments: -m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py, p. f$ L* y% F$ g1 l& `
) ]0 G& x" t( r# Q. c. V
Working directory: $FileDir$ , K9 Z. j) f+ q6 X' c k" j5 ^1 NPyRCC配置# d; ^8 t+ D! }' R% ^
. O& {: G7 W- `# y9 r
PyRCC主要是把编写的.qrc资源文件换成.py文件。在Pycharm中,依次打开 File – Settings – Tools – External Tools,点击 + Create Tool,配置如下:/ S+ R* Z2 R' T6 H4 {
+ V4 y* Z) `9 [2 _5 @3 h
Name: PyRCC . j9 X% c' c: Q/ B+ ` " k, f6 E6 E' d+ }Program: D:\Program Files\Python36\pyrcc5.exe # 当前rcc工具目录,请根据实际修改4 t: _6 R5 B1 g7 l9 U) D* j( P- G
# K% B+ [4 N# N% d
Arguments: $FileName$ -o $FileNameWithoutExtension$_rc.py / ]* h" @+ \2 h- ~! O+ ^) V" L- y' _$ J f: G8 t& V$ u
Working directory: $FileDir$3 {8 r3 k* `$ W- V$ `' [6 K0 K- k
PyQt5使用示例 : B% F# Q x4 t2 @% ^+ L7 h2 H# s! R1 Q% B3 R& n; w$ @" q( Q
创建一个空白的界面:0 B1 M) R9 {# X% q0 @7 h
$ h- C# ?* }" q: X3 p
import sys ' R# e6 x8 q4 t& q' _5 P$ C: u8 R ( d( L' N/ S1 I/ ~7 n, vfrom PyQt5.QtWidgets import QApplication, QMainWindow, QLabel5 w- d, _/ D. z) f0 N) L, \
: g7 B3 `4 l6 O, _
app = QApplication(sys.argv) & I1 h6 c% B0 Y v# I) E' C* l2 W& u9 W/ `
win = QMainWindow() ( o6 ^) b& p+ N* o4 _8 ~3 p \' s7 {6 o: Y
win.setGeometry(400, 400, 400, 300) T" K" ?1 C" q, _$ \" H
. w% Q. l3 `* s$ Y7 o8 u
win.setWindowTitle("Pyqt5 Tutorial"); Z7 C8 X1 @# z, i, c" M6 b. @! c
9 Z3 n% J0 T. j, q& f0 pwin.show() ; F+ ]2 u5 Q$ ~( B, U7 F4 j ! P, {+ ?3 z: X1 t& hsys.exit(app.exec_())$ K4 [. B) o3 u5 X# b& C
' Y: M5 Q. U+ q5 s
$ i5 F$ d5 @0 m7 ^
( P% {8 r& q* ^, `) G
其中:' Y) T" b) ?. N: ]' F3 s$ v/ z4 S
N: C3 ?! B4 N" B( v5 N- t. g
Qapplication():每个GUI都必须包含一个Qapplication,argv表示获取命令行参数,如果不用获取,则可以使用[]代替。 E8 g" v7 Z p. j/ ^5 r0 o 0 R: P6 e' \- h' GQMainWindow():类似一个容器(窗口)用来包含按钮、文本、输入框等widgets。arg标识可以获取命令行执行时的参数。 o( _. a* d; |" T8 ]5 |5 Y: j& s9 V' f0 H, C0 s
SetGeometry是用来定义 QMainWindow() 窗口的尺寸, 语法:setGeometry(x, y, width, height ),其中x,y为屏幕上的坐标点。 9 [( m3 I, V5 `- }0 O0 X! {$ z , L5 P, |- [4 o2 H0 w8 ^show():用来显示窗口! g$ F" k7 ~" a; ?3 t
9 F! H% [% {+ L' D- G$ _
exit(app.exec_()):设置窗口一直运行指导使用关闭按钮进行关闭 v) p5 h- B0 m) ] o2 [ l" X" O2 Z U6 k# a
PyQt5支持的常见Widgets有:+ a. A; Q/ }4 H% M( i/ p2 R2 ~
8 ?' _, W7 M+ V/ b
; M' O* q, m% R8 L ( G" Y* @ S2 c( ^7 F从上到下,从左到右依次为:Qlabel、QcomboBox、QcheckBox、QradioButton、QpushButton、QtableWidget、QlineEdit、Qslider、QProgressBar3 h, @) a: a( Y! q1 m0 r; L
+ _; G( E" M$ ~) c! _$ @对于使用Pyqt5设置文本内容,我们使用Qlabel: . _" o0 k2 u* i* @4 Y6 z: J( E, K
import sys$ y! ]* ~5 J; [2 i( v
8 L! A/ f% h, j6 T
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel* [0 h4 O% h/ H( r. ~1 x
2 i3 b' G# x1 Lapp = QApplication(sys.argv) * H# i: |+ I& a+ g. z Z ; Q( E+ w) H0 z# P& Qwin = QMainWindow() , z/ L$ E u+ E9 e o 0 a- D% W9 m) X* A( U. K% ~win.setGeometry(400, 400, 400, 300) * D2 Z" a( P. G$ M& t x$ q # \' K. k& Y) N& M4 Q# X; mwin.setWindowTitle("Pyqt5 Tutorial")1 Z8 I" {9 w9 p% r/ q2 b- E3 v
* C3 E/ }0 [' _6 f* `
\# Label Text " o M5 t8 f, s* M, Z6 \) ^- n ' g6 P4 G; n Y# h) ?8 Nlabel = QLabel(win): \7 D9 @2 L( ?) R1 L+ B
! g! F' m$ g* o ~3 p' \label.resize(200, 100)' p5 V1 }$ Z3 Z6 W$ _2 ?& B
9 h; W% ]+ F/ a/ ? D6 J$ {
label.setText("Hi this is Pyqt5")6 w1 z! D7 m6 X i
1 M4 ~. ?3 o2 f
label.move(100, 100) 1 |% s# ~+ k/ S8 } % j, J/ g. H0 s( V3 k& x3 u9 vwin.show()6 O8 V/ q. O5 W$ \+ O0 l- o% t# R5 c
& A; G6 |* @# ?" C4 l! v
sys.exit(app.exec_()) ' n0 X6 h V+ V o# L, J: O* K! j" c( J9 w% s: b S! B
9 n' j' ]( u1 y, h % ? b. J1 ^+ ^/ W按钮与事件:8 i: `. ^; B3 ~3 D( Y2 I9 [
& N6 Y& f% e- P3 K3 h8 P/ Mimport sys 1 E" I m# i E1 X & g* ]8 Q1 R0 ? x' |( v' j1 dfrom PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton! g: m$ `, I. x: P/ w
8 v* U3 P9 i E. i
def click():* ]( v3 K2 [% c1 ]6 S! ^
8 a- \' ]1 i6 I% I( r
print("Hy Button is clicked!") % C" j/ |* G9 c" [) _' B0 ] y5 K$ L- ~% Q0 q. i
app = QApplication(sys.argv)& N: c9 m6 r* } |2 \; R, w8 V
5 n' M- p) `$ }* C" ~9 f
win = QMainWindow(); E4 L# q- D% H7 A1 z/ Z8 |
2 q& e j& \) b3 Y9 G. J# vwin.setGeometry(400, 400, 400, 300) ) M) S/ b$ o7 t, L1 H* E5 `2 }' ?8 k+ o N
win.setWindowTitle("Pyqt5 Tutorial")/ R! x h8 Q9 o! W; D1 ~
4 n- M0 E$ p0 T2 q( ?4 p
\# Button5 T e2 U3 H0 j
+ ]/ D; z% x+ ~
button = QPushButton(win): f8 s2 M% [# j) C2 a$ K/ V
V4 N; e1 e+ m: c4 H! W% S- I- N
button.resize(200, 100) $ y4 Q4 u/ g! @ + T/ n$ [6 m6 }button.setText("Hi! Click Me")5 u. L/ n2 k% ]0 k
. F$ _$ l! e( t* ^& J" x3 s6 A
button.move(100, 100) / z$ y7 N! P/ P8 H6 R" Q# `; Y. {" |* ^$ M/ j9 [. }- E$ t3 W
button.clicked.connect(click) " N B, Y6 }# K+ S$ m- V) o' D x7 z `" {
win.show() : x2 O& L& m; U9 _3 D+ O- j$ P0 T % f$ J5 i2 i& o' D0 x/ f6 _sys.exit(app.exec_()) " y3 T& d& Y+ j0 f: s1 g u0 @ " z) B& O& e1 y . r7 b- q+ x! P8 M" _$ ^5 v4 `3 Q3 Y! z J: D; p* ?
button.clicked.connect() 在按钮点击后执行特定的事件。 8 g! k* n" `3 Y; R0 e! P% o : h3 b/ c0 v% M. m! |PyQt5实战 % L7 M- k9 r" Y8 c / S; G% o8 D1 j- C6 P- M/ ^实战项目:简易的天气查询软件 & h1 F1 w* f U( `5 o 6 B5 {4 W6 c" U1 y- e1、使用Qt Designer设计一个界面 * H! Q) ~5 S( @6 O: I - a1 k6 |" y: A3 a4 X4 Z 1 E3 B. l8 K7 Y0 m3 l 6 T6 H" @5 x, A) r! w$ z' b, b; L用到的控件有Button, GroupBox, Label,ComboBox,TextEdit,同时定义了两个按钮queryBtn及clearBtn,分别用来查询及清空天气数据。我们需要绑定槽函数,方法如下: 5 j2 `. v; H* c3 K# d1 K5 S9 ?! O; R' @8 _8 F
在Qt Designer右下角选择 信号/槽编辑器,点击+号新增 6 r0 I* l7 w& ?/ b- q' Z) ] , C' e3 I! d5 [. R8 k- H1 j分别选择queryBtn及clearBtn,选择信号 clicked(), 接收者 Dialog 及槽 accept(),(槽函数这里不知道如何定义,后期在代码里再进行修改) 1 @+ ^1 F$ M* s5 ]% ~* j9 G# G& W 7 G1 Y. X( p$ m, Y$ j$ \+ s以上完成后保存为Weather.ui文件。 " v, ~5 u) ]9 U6 E) G, I5 H4 H" V0 M/ G$ r& j9 t6 y2 u2 \
2、转换.ui文件为.py文件0 ]6 a: h Q j, b8 Q+ `/ \7 |
$ o5 V5 @- R5 M" h8 P
PyQt5支持直接使用.ui文件:9 s4 i3 E2 S$ \: r$ i
4 ^2 \- Q1 q ]1 V- m- p
import sys _& r" ~& v/ z
: ^4 _ f* u3 ~# m/ F; y! Z. ^" w' Q
from PyQt5 import QtWidgets, uic " Z3 N* I8 j3 z2 g% j% f1 V 3 A- c/ r S% ]/ Iapp = QtWidgets.QApplication(sys.argv) A8 A. B% m, k" m" e
: o0 M3 V/ m" z1 r! |window = uic.loadUi("mainwindow.ui") ( c$ }/ B- N& |- U4 @+ d% H ! D& o- S+ e+ `7 kwindow.show()' V7 m* M3 g5 H" R* {
2 y4 Q& U" l) K; T' E* A
app.exec()/ {9 h. t; y$ C+ U; z6 A
但是为了更好的自定义及修改上面的槽函数,可以使用External Tools – PyUIC,即可生成Weather.py,实际运行命令如下:2 `4 w3 Z, D. g
! O m4 g X) |# X' R& ~6 H
D:\Program Files\Python36\python.exe -m PyQt5.uic.pyuic Weather.ui -o Weather.py & e9 a' @$ W1 K; f( q2 n# f- U, M其中,我们需要把两个按钮绑定的槽函数: 7 l8 |- o( I. R; f) {& u8 h7 z; L* j! T' h
\# self.queryBtn.clicked.connect(Dialog.accept)0 S) d- c' w2 ?
/ e' |$ J8 b) s2 Q0 ^6 F
\# self.clearBtn.clicked.connect(Dialog.accept)3 ?, n1 ]8 C, D" h) E* u# H
* d: @ d% U. k\# 修改为: ! r3 k1 H( h h: c0 ^ 6 }0 A/ @& Y2 w! K0 J% u3 pself.queryBtn.clicked.connect(Dialog.queryWeather) % j e6 W0 ^8 u6 M9 }% k( a6 t- n1 G1 z& X g
self.clearBtn.clicked.connect(Dialog.clearText)4 I, Q& h* E P8 b( g% S
最终的Weather.py内容如下: " z0 c5 f; |. j0 R2 K; d' Z5 c s$ C
\# -*- coding: utf-8 -*-% `/ P! e1 }) v7 T: M
9 t2 \& t' u4 r& B- C
\# Form implementation generated from reading ui file 'Weather.ui' & a/ v( m" O) w7 c/ `2 N$ L! Y& y 8 V" |" d) U* T* [ w: Z4 p\# $ A- Q5 } n! W ) t* ~: w! x# [' B\# Created by: PyQt5 UI code generator 5.15.4* _# N# n7 U* [. ]
* o' z0 Y9 m& w: M( G, Y\# % e5 W) i9 j' {. ?7 p * W0 H) T; l0 ~7 i5 r\# WARNING: Any manual changes made to this file will be lost when pyuic5 is% O' c3 n" L: `
; Q1 ~( @( x5 C' @
\# run again. Do not edit this file unless you know what you are doing. $ U( Y/ O6 W$ r . Q4 a+ w4 H( U1 T( g6 N% I5 _from PyQt5 import QtCore, QtGui, QtWidgets+ ? ~( ]- F* ]& h
% F5 ?& N. m) g# ~, Fclass Ui_Dialog(object):) ]; d5 B4 |) K
8 S3 m3 E/ D4 B; o% l( G
def setupUi(self, Dialog):3 ^7 B/ k' M+ j) y k. {/ @
+ K( u2 H: X' O/ ^5 b Dialog.setObjectName("Dialog") ) s. [5 V4 B8 t3 N' P) U" _& E; A " a9 l; \; ~) t1 F4 H Dialog.resize(600, 600)4 I9 S, w( O0 u4 N
7 k* e o7 B+ L. X; Y, k self.comboBox.addItem("") 5 w* k4 |/ N: i. J/ D, d" Y; O: p1 c# P6 g1 N
self.comboBox.addItem("") 4 P, e3 s X9 L5 I! z# m' O S* r* J9 r: t- h, z7 |
self.comboBox.addItem("")1 d% G8 K; N0 e1 U9 W
" J! k: u l* a' B0 t3 k
self.textEdit = QtWidgets.QTextEdit(self.groupBox) ! A3 \1 }- j ]0 {2 \" l( `6 u$ E8 v# T! Y
self.textEdit.setGeometry(QtCore.QRect(20, 70, 491, 411)) ' X* m1 p* M" p# C" d& |- |2 E! ]; d9 m) \( Y% ?& m
self.textEdit.setObjectName("textEdit") 1 V. l# g: H+ p$ N, s! E# m+ F3 ?" t( q( Z4 V4 N8 L4 e% T
self.queryBtn = QtWidgets.QPushButton(Dialog)6 p k' f( s! x& ]0 d8 e
A0 n: D1 r. r, z5 e \( K self.queryBtn.setGeometry(QtCore.QRect(490, 560, 93, 28))' ?5 v+ D: b/ o, f0 {
$ }2 ~; g n, B
self.queryBtn.setObjectName("queryBtn") ( i- _4 m5 s; y. E- {1 G# E 0 P6 n0 ~6 H+ m9 I2 g& }. R# u self.clearBtn = QtWidgets.QPushButton(Dialog) 0 s B3 F: s R6 Y7 V7 ] - v/ k6 v5 Z: g/ o7 `& K4 u; _' L self.clearBtn.setGeometry(QtCore.QRect(30, 560, 93, 28)). l4 o* R. k# V# Y
8 l/ d9 J$ Y% N/ v
self.clearBtn.setObjectName("clearBtn")0 r# E, O' O" T3 N
9 c: g, N7 l% Z* G- x self.retranslateUi(Dialog) p' R* r9 t. H* [, _& _6 C9 \4 b
1 v# W; l6 `* y1 n- s8 G
self.clearBtn.clicked.connect(Dialog.clearText) 5 q; x9 y: {: h) V$ R' _" W : z. @0 V T# W self.queryBtn.clicked.connect(Dialog.queryWeather)) |4 }1 ^4 r" O9 X6 X, w6 [% s
! n! y8 ~' [1 E
QtCore.QMetaObject.connectSlotsByName(Dialog) " f' |1 [ }. ^% t2 d' t' ^/ y' `, A6 ~2 B. ^
def retranslateUi(self, Dialog):3 E/ [' a( a0 f" K' _/ o4 g
9 v3 b1 T0 R* ^, `, _% K0 M1 V
_translate = QtCore.QCoreApplication.translate + i4 z# m' J/ B. L2 b' _7 V9 k7 i, X; W
Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 9 I, F; q2 a# c8 I& d9 A5 L4 m3 A X7 l6 V/ u* N/ p4 o self.groupBox.setTitle(_translate("Dialog", "城市天气预报"))# L- z8 ?/ N0 R& _# U+ M( `( R
: _: m& v7 i- q: C4 y C
self.label_2.setText(_translate("Dialog", "城市")) ( N* l# t+ i1 e0 D1 M1 R( B* ]2 t3 ]1 y" y- @9 |7 m3 T, H8 d
self.comboBox.setItemText(0, _translate("Dialog", "北京"))9 o% M$ g0 q: E6 w
9 Z/ C4 M# g; @# T' x: @. @
self.comboBox.setItemText(1, _translate("Dialog", "苏州")) , U6 M4 v3 B5 z, [) k; z ' ^# Q( b- N& C self.comboBox.setItemText(2, _translate("Dialog", "上海")) 9 S* K: e7 ]( s+ c) a3 h4 [3 h; \, W- h+ g8 k- c
self.queryBtn.setText(_translate("Dialog", "查询")) 3 i: f9 _ {" Q ' r/ F9 ~1 M( Z5 q0 j' X self.clearBtn.setText(_translate("Dialog", "清空")) * I: c: X( T% a4 C% D# ^- [8 E/ o2 x
3、调用MainDialog8 v a" }) Z# D& s