PyQt5安裝
pip install pyqt5
第一個gui程序
語法一
import sys from PyQt5.QtWidgets import QApplication, QWidget if __name__ == '__main__': # 創建QApplication類的實例 app = QApplication(sys.argv) # 創建一個窗口 w = QWidget() # 設置窗口的尺寸 w.resize(600, 300) # 移動窗口 w.move(300, 300) # 設置窗口的標題 w.setWindowTitle('第一個基於PyQt5的桌面應用') # 顯示窗口 w.show() # 進入程序的主循環、並通過exit函數確保主循環安全結束 sys.exit(app.exec_())
語法二
import sys from PyQt5.QtWidgets import QApplication, QWidget class FirstMainWin(QWidget): def __init__(self): super(FirstMainWin, self).__init__() # 設置主窗口的標題 self.setWindowTitle('第一個主窗口應用') # 設置窗口的尺寸 self.resize(400, 300) if __name__ == '__main__': app = QApplication(sys.argv) main = FirstMainWin() main.show() sys.exit(app.exec_())
安裝和配置Qt Designer
安裝Anconda
anaconda自帶Qt
Pycharm 配置Qt
Qt Designer快速入門
1.ui文件
1.創建住窗口
2.創建組件
左側工具欄,右側屬性欄,中間窗口欄
(拖動左側到的組件中間可創建組件)
3.保存qt文件.ui
2.ui轉py
命令方式:
python -m PyQt5.uic.pyuic demo.ui -o demo.py
Pycharm方式:
-m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py
基礎窗口控件
QLabel控件

''' QLabel控件 setAlignment():設置文本的對齊方式 setIndent():設置文本縮進 text():獲取文本內容 setBuddy():設置伙伴關系 setText():設置文本內容 selectedText():返回所選擇的字符 setWordWrap():設置是否允許換行 QLabel常用的信號(事件): 1. 當鼠標滑過QLabel控件時觸發:linkHovered 2. 當鼠標單擊QLabel控件時觸發:linkActivated ''' import sys from PyQt5.QtWidgets import QVBoxLayout, QMainWindow, QApplication, QLabel, QWidget from PyQt5.QtGui import QPixmap, QPalette from PyQt5.QtCore import Qt class QLabelDemo(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): label1 = QLabel(self) label2 = QLabel(self) label3 = QLabel(self) label4 = QLabel(self) label1.setText("<font color=yellow>這是一個文本標簽.</font>") label1.setAutoFillBackground(True) palette = QPalette() palette.setColor(QPalette.Window, Qt.blue) # 設置背景色 label1.setPalette(palette) label1.setAlignment(Qt.AlignCenter) label2.setText("<a href='#'>歡迎使用Python GUI程序</a>") label3.setAlignment(Qt.AlignCenter) label3.setToolTip('這是一個圖片標簽') label3.setPixmap(QPixmap("./images/python.jpg")) # 如果設為True,用瀏覽器打開網頁,如果設為False,調用槽函數 label4.setOpenExternalLinks(True) label4.setText("<a href='https://item.jd.com/12417265.html'>感謝關注《Python從菜鳥到高手》</a>") label4.setAlignment(Qt.AlignRight) label4.setToolTip('這是一個超級鏈接') vbox = QVBoxLayout() vbox.addWidget(label1) vbox.addWidget(label2) vbox.addWidget(label3) vbox.addWidget(label4) label2.linkHovered.connect(self.linkHovered) label4.linkActivated.connect(self.linkClicked) self.setLayout(vbox) self.setWindowTitle('QLabel控件演示') def linkHovered(self): print('當鼠標滑過label2標簽時,觸發事件') def linkClicked(self): print('當鼠標單擊label4標簽時,觸發事件') if __name__ == '__main__': app = QApplication(sys.argv) main = QLabelDemo() main.show() sys.exit(app.exec_())

''' QLabel與伙伴控件 mainLayout.addWidget(控件對象,rowIndex,columnIndex,row,column) ''' from PyQt5.QtWidgets import * import sys class QLabelBuddy(QDialog) : def __init__(self): super().__init__() self.initUI() def initUI(self): self.setWindowTitle('QLabel與伙伴控件') nameLabel = QLabel('&Name',self) nameLineEdit = QLineEdit(self) # 設置伙伴控件 nameLabel.setBuddy(nameLineEdit) passwordLabel = QLabel('&Password',self) passwordLineEdit = QLineEdit(self) # 設置伙伴控件 passwordLabel.setBuddy(passwordLineEdit) btnOK = QPushButton('&OK') btnCancel = QPushButton('&Cancel') mainLayout = QGridLayout(self) mainLayout.addWidget(nameLabel,0,0) mainLayout.addWidget(nameLineEdit,0,1,1,2) mainLayout.addWidget(passwordLabel,1,0) mainLayout.addWidget(passwordLineEdit,1,1,1,2) mainLayout.addWidget(btnOK,2,1) mainLayout.addWidget(btnCancel,2,2) if __name__ == '__main__': app = QApplication(sys.argv) main = QLabelBuddy() main.show() sys.exit(app.exec_())
QLineEdit控件

''' QLineEdit控件與回顯模式 基本功能:輸入單行的文本 EchoMode(回顯模式) 4種回顯模式 1. Normal 2. NoEcho 3. Password 4. PasswordEchoOnEdit Mac : Command Windows:Control ''' from PyQt5.QtWidgets import * import sys class QLineEditEchoMode(QWidget): def __init__(self): super(QLineEditEchoMode, self).__init__() self.initUI() def initUI(self): self.setWindowTitle('文本輸入框的回顯模式') formLayout = QFormLayout() normalLineEdit = QLineEdit() noEchoLineEdit = QLineEdit() passwordLineEdit = QLineEdit() passwordEchoOnEditLineEdit = QLineEdit() formLayout.addRow("Normal", normalLineEdit) formLayout.addRow("NoEcho", noEchoLineEdit) formLayout.addRow("Password", passwordLineEdit) formLayout.addRow("PasswordEchoOnEdit", passwordEchoOnEditLineEdit) # placeholdertext normalLineEdit.setPlaceholderText("Normal") noEchoLineEdit.setPlaceholderText("NoEcho") passwordLineEdit.setPlaceholderText("Password") passwordEchoOnEditLineEdit.setPlaceholderText("PasswordEchoOnEdit") normalLineEdit.setEchoMode(QLineEdit.Normal) noEchoLineEdit.setEchoMode(QLineEdit.NoEcho) passwordLineEdit.setEchoMode(QLineEdit.Password) passwordEchoOnEditLineEdit.setEchoMode(QLineEdit.PasswordEchoOnEdit) self.setLayout(formLayout) if __name__ == '__main__': app = QApplication(sys.argv) main = QLineEditEchoMode() main.show() sys.exit(app.exec_())

''' 現在QLineEdit控件的輸入(校驗器) 如限制只能輸入整數、浮點數或滿足一定條件的字符串 ''' from PyQt5.QtWidgets import * from PyQt5.QtGui import QIntValidator, QDoubleValidator, QRegExpValidator from PyQt5.QtCore import QRegExp import sys class QLineEditValidator(QWidget): def __init__(self): super(QLineEditValidator, self).__init__() self.initUI() def initUI(self): self.setWindowTitle('校驗器') # 創建表單布局 formLayout = QFormLayout() intLineEdit = QLineEdit() doubleLineEdit = QLineEdit() validatorLineEdit = QLineEdit() formLayout.addRow('整數類型', intLineEdit) formLayout.addRow('浮點類型', doubleLineEdit) formLayout.addRow('數字和字母', validatorLineEdit) intLineEdit.setPlaceholderText('整型') doubleLineEdit.setPlaceholderText('浮點型') validatorLineEdit.setPlaceholderText('字母和數字') # 整數校驗器 [1,99] intValidator = QIntValidator(self) intValidator.setRange(1, 99) # 浮點校驗器 [-360,360],精度:小數點后2位 doubleValidator = QDoubleValidator(self) doubleValidator.setRange(-360, 360) doubleValidator.setNotation(QDoubleValidator.StandardNotation) # 設置精度,小數點2位 doubleValidator.setDecimals(2) # 字符和數字 reg = QRegExp('[a-zA-z0-9]+$') validator = QRegExpValidator(self) validator.setRegExp(reg) # 設置校驗器 intLineEdit.setValidator(intValidator) doubleLineEdit.setValidator(doubleValidator) validatorLineEdit.setValidator(validator) self.setLayout(formLayout) if __name__ == '__main__': app = QApplication(sys.argv) main = QLineEditValidator() main.show() sys.exit(app.exec_())

''' 用掩碼限制QLineEdit控件的輸入 A ASCII字母字符是必須輸入的(A-Z、a-z) a ASCII字母字符是允許輸入的,但不是必需的(A-Z、a-z) N ASCII字母字符是必須輸入的(A-Z、a-z、0-9) n ASII字母字符是允許輸入的,但不是必需的(A-Z、a-z、0-9) X 任何字符都是必須輸入的 x 任何字符都是允許輸入的,但不是必需的 9 ASCII數字字符是必須輸入的(0-9) 0 ASCII數字字符是允許輸入的,但不是必需的(0-9) D ASCII數字字符是必須輸入的(1-9) d ASCII數字字符是允許輸入的,但不是必需的(1-9) # ASCI數字字符或加減符號是允許輸入的,但不是必需的 H 十六進制格式字符是必須輸入的(A-F、a-f、0-9) h 十六進制格式字符是允許輸入的,但不是必需的(A-F、a-f、0-9) B 二進制格式字符是必須輸入的(0,1) b 二進制格式字符是允許輸入的,但不是必需的(0,1) > 所有的字母字符都大寫 < 所有的字母字符都小寫 ! 關閉大小寫轉換 \ 使用"\"轉義上面列出的字符 ''' from PyQt5.QtWidgets import * import sys class QLineEditMask(QWidget): def __init__(self): super(QLineEditMask, self).__init__() self.initUI() def initUI(self): self.setWindowTitle('用掩碼限制QLineEdit控件的輸入') formLayout = QFormLayout() ipLineEdit = QLineEdit() macLineEdit = QLineEdit() dateLineEdit = QLineEdit() licenseLineEdit = QLineEdit() # 192.168.21.45 ipLineEdit.setInputMask('000.000.000.000;_') macLineEdit.setInputMask('HH:HH:HH:HH:HH:HH;_') dateLineEdit.setInputMask('0000-00-00') licenseLineEdit.setInputMask('>AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;#') formLayout.addRow('數字掩碼', ipLineEdit) formLayout.addRow('Mac掩碼', macLineEdit) formLayout.addRow('日期掩碼', dateLineEdit) formLayout.addRow('許可證掩碼', licenseLineEdit) self.setLayout(formLayout) if __name__ == '__main__': app = QApplication(sys.argv) main = QLineEditMask() main.show() sys.exit(app.exec_())

''' QLineEdit綜合案例 ''' from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import Qt import sys class QLineEditDemo(QWidget): def __init__(self): super(QLineEditDemo,self).__init__() self.initUI() def initUI(self): edit1 = QLineEdit() # 使用int校驗器 edit1.setValidator(QIntValidator()) edit1.setMaxLength(4) # 不超過9999 edit1.setAlignment(Qt.AlignRight) edit1.setFont(QFont('Arial',20)) edit2 = QLineEdit() edit2.setValidator(QDoubleValidator(0.99,99.99,2)) edit3 = QLineEdit() edit3.setInputMask('99_9999_999999;#') edit4 = QLineEdit() edit4.textChanged.connect(self.textChanged) edit5 = QLineEdit() edit5.setEchoMode(QLineEdit.Password) edit5.editingFinished.connect(self.enterPress) edit6 = QLineEdit('Hello PyQt5') edit6.setReadOnly(True) formLayout = QFormLayout() formLayout.addRow('整數校驗',edit1) formLayout.addRow('浮點數校驗',edit2) formLayout.addRow('Input Mask',edit3) formLayout.addRow('文本變化', edit4) formLayout.addRow('密碼',edit5) formLayout.addRow('只讀',edit6) self.setLayout(formLayout) self.setWindowTitle('QLineEdit綜合案例') def textChanged(self,text): print('輸入的內容:' + text) def enterPress(self): print('已輸入值') if __name__ == '__main__': app = QApplication(sys.argv) main = QLineEditDemo() main.show() sys.exit(app.exec_())
QTextEdit控件

''' QTextEdit控件 ''' from PyQt5.QtWidgets import * import sys class QTextEditDemo(QWidget): def __init__(self): super(QTextEditDemo, self).__init__() self.initUI() def initUI(self): self.setWindowTitle('QTextEdit控件演示') self.resize(300, 320) self.textEdit = QTextEdit() self.buttonText = QPushButton('顯示文本') self.buttonHTML = QPushButton('顯示HTML') self.buttonToText = QPushButton('獲取文本') self.buttonToHTML = QPushButton('獲取HTML') layout = QVBoxLayout() layout.addWidget(self.textEdit) layout.addWidget(self.buttonText) layout.addWidget(self.buttonToText) layout.addWidget(self.buttonHTML) layout.addWidget(self.buttonToHTML) self.setLayout(layout) self.buttonText.clicked.connect(self.onClick_ButtonText) self.buttonHTML.clicked.connect(self.onClick_ButtonHTML) self.buttonToText.clicked.connect(self.onClick_ButtonToText) self.buttonToHTML.clicked.connect(self.onClick_ButtonToHTML) def onClick_ButtonText(self): self.textEdit.setPlainText('Hello World,世界你好嗎?') def onClick_ButtonToText(self): print(self.textEdit.toPlainText()) def onClick_ButtonHTML(self): self.textEdit.setHtml('<font color="blue" size="5">Hello World</font>') def onClick_ButtonToHTML(self): print(self.textEdit.toHtml()) if __name__ == '__main__': app = QApplication(sys.argv) main = QTextEditDemo() main.show() sys.exit(app.exec_())
QPushButton控件

''' 按鈕控件(QPushButton) QAbstractButton QPushButton AToolButton QRadioButton QCheckBox ''' import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class QPushButtonDemo(QDialog): def __init__(self): super(QPushButtonDemo, self).__init__() self.initUI() def initUI(self): self.setWindowTitle('QPushButton Demo') layout = QVBoxLayout() self.button1 = QPushButton('第1個按鈕') self.button1.setText('First Button1') self.button1.setCheckable(True) self.button1.toggle() self.button1.clicked.connect(self.buttonState) self.button1.clicked.connect(lambda: self.whichButton(self.button1)) layout.addWidget(self.button1) # 在文本前面顯示圖像 self.button2 = QPushButton('圖像按鈕') self.button2.setIcon(QIcon(QPixmap('./images/python.png'))) self.button2.clicked.connect(lambda: self.whichButton(self.button2)) layout.addWidget(self.button2) self.button3 = QPushButton('不可用的按鈕') self.button3.setEnabled(False) layout.addWidget(self.button3) self.button4 = QPushButton('&MyButton') self.button4.setDefault(True) self.button4.clicked.connect(lambda: self.whichButton(self.button4)) layout.addWidget(self.button4) self.setLayout(layout) self.resize(400, 300) def buttonState(self): if self.button1.isChecked(): print('按鈕1已經被選中') else: print('按鈕1未被選中') def whichButton(self, btn): print('被單擊的按鈕是<' + btn.text() + '>') if __name__ == '__main__': app = QApplication(sys.argv) main = QPushButtonDemo() main.show() sys.exit(app.exec_())
QRadioButton控件

''' 單選按鈕控件(QRadioButton) ''' import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class QRadioButtonDemo(QWidget): def __init__(self): super(QRadioButtonDemo, self).__init__() self.initUI() def initUI(self): self.setWindowTitle('QRadioButton') layout = QHBoxLayout() self.button1 = QRadioButton('單選按鈕1') self.button1.setChecked(True) self.button1.toggled.connect(self.buttonState) layout.addWidget(self.button1) self.button2 = QRadioButton('單選按鈕2') self.button2.toggled.connect(self.buttonState) layout.addWidget(self.button2) self.setLayout(layout) def buttonState(self): radioButton = self.sender() if radioButton.isChecked() == True: print('<' + radioButton.text() + '> 被選中') else: print('<' + radioButton.text() + '> 被取消選中狀態') if __name__ == '__main__': app = QApplication(sys.argv) main = QRadioButtonDemo() main.show() sys.exit(app.exec_())
QCheckBox控件

''' 復選框控件(QCheckBox) 3種狀態 未選中:0 半選中:1 選中:2 ''' import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtCore import Qt class QCheckBoxDemo(QWidget): def __init__(self): super(QCheckBoxDemo, self).__init__() self.initUI() def initUI(self): self.setWindowTitle('復選框控件演示') layout = QHBoxLayout() self.checkBox1 = QCheckBox('復選框控件1') self.checkBox1.setChecked(True) self.checkBox1.stateChanged.connect(lambda: self.checkboxState(self.checkBox1)) layout.addWidget(self.checkBox1) self.checkBox2 = QCheckBox('復選框控件2') self.checkBox2.stateChanged.connect(lambda: self.checkboxState(self.checkBox2)) layout.addWidget(self.checkBox2) self.checkBox3 = QCheckBox('半選中') self.checkBox3.stateChanged.connect(lambda: self.checkboxState(self.checkBox3)) self.checkBox3.setTristate(True) self.checkBox3.setCheckState(Qt.PartiallyChecked) layout.addWidget(self.checkBox3) self.setLayout(layout) def checkboxState(self, cb): check1Status = self.checkBox1.text() + ', isChecked=' + str(self.checkBox1.isChecked()) + ',checkState=' + str( self.checkBox1.checkState()) + '\n' check2Status = self.checkBox2.text() + ', isChecked=' + str(self.checkBox2.isChecked()) + ',checkState=' + str( self.checkBox2.checkState()) + '\n' check3Status = self.checkBox3.text() + ', isChecked=' + str(self.checkBox3.isChecked()) + ',checkState=' + str( self.checkBox3.checkState()) + '\n' print(check1Status + check2Status + check3Status) if __name__ == '__main__': app = QApplication(sys.argv) main = QCheckBoxDemo() main.show() sys.exit(app.exec_())
QComboBox控件

''' 下拉列表控件(QComboBox) 1. 如果將列表項添加到QComboBox控件中 2. 如何獲取選中的列表項 ''' import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class QComboBoxDemo(QWidget): def __init__(self): super(QComboBoxDemo, self).__init__() self.initUI() def initUI(self): self.setWindowTitle('下拉列表控件演示') self.resize(300, 100) layout = QVBoxLayout() self.label = QLabel('請選擇編程語言') self.cb = QComboBox() self.cb.addItem('C++') self.cb.addItem('Python') self.cb.addItems(['Java', 'C#', 'Ruby']) self.cb.currentIndexChanged.connect(self.selectionChange) layout.addWidget(self.label) layout.addWidget(self.cb) self.setLayout(layout) def selectionChange(self, i): self.label.setText(self.cb.currentText()) self.label.adjustSize() for count in range(self.cb.count()): print('item' + str(count) + '=' + self.cb.itemText(count)) print('current index', i, 'selection changed', self.cb.currentText()) if __name__ == '__main__': app = QApplication(sys.argv) main = QComboBoxDemo() main.show() sys.exit(app.exec_())
QSpinBox控件

''' 計數器控件(QSpinBox) ''' import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class QSpinBoxDemo(QWidget): def __init__(self): super(QSpinBoxDemo,self).__init__() self.initUI() def initUI(self): self.setWindowTitle('QSpinBox演示') self.resize(300,100) layout = QVBoxLayout() self.label = QLabel('當前值') self.label.setAlignment(Qt.AlignCenter) layout.addWidget(self.label) self.sb = QSpinBox() self.sb.setValue(18) self.sb.setRange(10,38) self.sb.setSingleStep(3) layout.addWidget(self.sb) self.sb.valueChanged.connect(self.valueChange) self.setLayout(layout) def valueChange(self): self.label.setText('當前值:' + str(self.sb.value())) if __name__ == '__main__': app = QApplication(sys.argv) main = QSpinBoxDemo() main.show() sys.exit(app.exec_())
QSlider控件

''' 滑塊控件(QSlider) ''' import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class QSliderDemo(QWidget): def __init__(self): super(QSliderDemo, self).__init__() self.initUI() def initUI(self): self.setWindowTitle('滑塊控件演示') self.resize(300, 700) layout = QVBoxLayout() self.label = QLabel('你好 PyQt5') self.label.setAlignment(Qt.AlignCenter) layout.addWidget(self.label) self.slider = QSlider(Qt.Horizontal) # 設置最小值 self.slider.setMinimum(12) # 設置最大值 self.slider.setMaximum(48) # 步長 self.slider.setSingleStep(3) # 設置當前值 self.slider.setValue(18) # 設置刻度的位置,刻度在下方 self.slider.setTickPosition(QSlider.TicksBelow) # 設置刻度的間隔 self.slider.setTickInterval(6) layout.addWidget(self.slider) self.slider.valueChanged.connect(self.valueChange) self.slider1 = QSlider(Qt.Vertical) layout.addWidget(self.slider1) # 設置最小值 self.slider1.setMinimum(10) # 設置最大值 self.slider1.setMaximum(60) # 步長 self.slider1.setSingleStep(5) # 設置當前值 self.slider1.setValue(30) # 設置刻度的位置,刻度在下方 self.slider1.setTickPosition(QSlider.TicksLeft) # 設置刻度的間隔 self.slider1.setTickInterval(2) self.slider1.valueChanged.connect(self.valueChange) self.setLayout(layout) def valueChange(self): print('當前值:%s' % self.sender().value()) size = self.sender().value() self.label.setFont(QFont('Arial', size)) if __name__ == '__main__': app = QApplication(sys.argv) main = QSliderDemo() main.show() sys.exit(app.exec_())
對話框
通用對話框

''' 對話框:QDialog QMessageBox QColorDialog QFileDialog QFontDialog QInputDialog QMainWindow QWidget QDialog ''' import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class QDialogDemo(QMainWindow): def __init__(self): super(QDialogDemo, self).__init__() self.initUI() def initUI(self): self.setWindowTitle('QDialog案例') self.resize(300, 200) self.button = QPushButton(self) self.button.setText('彈出對話框') self.button.move(50, 50) self.button.clicked.connect(self.showDialog) def showDialog(self): dialog = QDialog() button = QPushButton('確定', dialog) button.clicked.connect(dialog.close) button.move(50, 50) dialog.setWindowTitle('對話框') dialog.setWindowModality(Qt.ApplicationModal) dialog.exec() if __name__ == '__main__': app = QApplication(sys.argv) main = QDialogDemo() main.show() sys.exit(app.exec_())
消息對話框

''' 消息對話框:QMessageBox 1. 關於對話框 2. 錯誤對話框 3. 警告對話框 4. 提問對話框 5. 消息對話框 有2點差異 1. 顯示的對話框圖標可能不同 2. 顯示的按鈕是不一樣的 ''' import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class QMessageBoxDemo(QWidget): def __init__(self): super(QMessageBoxDemo, self).__init__() self.initUI() def initUI(self): self.setWindowTitle('QMessageBox案例') self.resize(300, 400) layout = QVBoxLayout() self.button1 = QPushButton() self.button1.setText('顯示關於對話框') self.button1.clicked.connect(self.showDialog) self.button2 = QPushButton() self.button2.setText('顯示消息對話框') self.button2.clicked.connect(self.showDialog) self.button3 = QPushButton() self.button3.setText('顯示警告對話框') self.button3.clicked.connect(self.showDialog) self.button4 = QPushButton() self.button4.setText('顯示錯誤對話框') self.button4.clicked.connect(self.showDialog) self.button5 = QPushButton() self.button5.setText('顯示提問對話框') self.button5.clicked.connect(self.showDialog) layout.addWidget(self.button1) layout.addWidget(self.button2) layout.addWidget(self.button3) layout.addWidget(self.button4) layout.addWidget(self.button5) self.setLayout(layout) def showDialog(self): text = self.sender().text() if text == '顯示關於對話框': QMessageBox.about(self, '關於', '這是一個關於對話框') elif text == '顯示消息對話框': reply = QMessageBox.information(self, '消息', '這是一個消息對話框', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) print(reply == QMessageBox.Yes) elif text == '顯示警告對話框': QMessageBox.warning(self, '警告', '這是一個警告對話框', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) elif text == '顯示錯誤對話框': QMessageBox.critical(self, '警告', '這是一個警告對話框', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) elif text == '顯示提問對話框': QMessageBox.question(self, '警告', '這是一個警告對話框', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) if __name__ == '__main__': app = QApplication(sys.argv) main = QMessageBoxDemo() main.show() sys.exit(app.exec_())
輸入對話框

''' 輸入對話框:QInputDialog QInputDialog.getItem QInputDialog.getText QInputDialog.getInt ''' import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class QInputDialogDemo(QWidget): def __init__(self): super(QInputDialogDemo, self).__init__() self.initUI() def initUI(self): self.setWindowTitle('輸入對話框') layout = QFormLayout() self.button1 = QPushButton('獲取列表中的選項') self.button1.clicked.connect(self.getItem) self.lineEdit1 = QLineEdit() layout.addRow(self.button1, self.lineEdit1) self.button2 = QPushButton('獲取字符串') self.button2.clicked.connect(self.getText) self.lineEdit2 = QLineEdit() layout.addRow(self.button2, self.lineEdit2) self.button3 = QPushButton('獲取整數') self.button3.clicked.connect(self.getInt) self.lineEdit3 = QLineEdit() layout.addRow(self.button3, self.lineEdit3) self.setLayout(layout) def getItem(self): items = ('C', 'C++', 'Ruby', 'Python', 'Java') item, ok = QInputDialog.getItem(self, '請選擇編程語言', '語言列表', items) if ok and item: self.lineEdit1.setText(item) def getText(self): text, ok = QInputDialog.getText(self, '文本輸入框', '輸入姓名') if ok and text: self.lineEdit2.setText(text) def getInt(self): num, ok = QInputDialog.getInt(self, '整數輸入框', '輸入數字') if ok and num: self.lineEdit3.setText(str(num)) if __name__ == '__main__': app = QApplication(sys.argv) main = QInputDialogDemo() main.show() sys.exit(app.exec_())
字體對話框

''' 字體對話框:QFontDialog ''' import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class QFontDialogDemo(QWidget): def __init__(self): super(QFontDialogDemo, self).__init__() self.initUI() def initUI(self): self.setWindowTitle('Font Dialog例子') layout = QVBoxLayout() self.fontButton = QPushButton('選擇字體') self.fontButton.clicked.connect(self.getFont) layout.addWidget(self.fontButton) self.fontLabel = QLabel('Hello,測試字體例子') layout.addWidget(self.fontLabel) self.setLayout(layout) def getFont(self): font, ok = QFontDialog.getFont() if ok: self.fontLabel.setFont(font) if __name__ == '__main__': app = QApplication(sys.argv) main = QFontDialogDemo() main.show() sys.exit(app.exec_())
顏色對話框

''' 顏色對話框:QColorDialog ''' ''' 字體對話框:QFontDialog ''' import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class QColorDialogDemo(QWidget): def __init__(self): super(QColorDialogDemo, self).__init__() self.initUI() def initUI(self): self.setWindowTitle('Color Dialog例子') layout = QVBoxLayout() self.colorButton = QPushButton('設置顏色') self.colorButton.clicked.connect(self.getColor) layout.addWidget(self.colorButton) self.colorButton1 = QPushButton('設置背景顏色') self.colorButton1.clicked.connect(self.getBGColor) layout.addWidget(self.colorButton1) self.colorLabel = QLabel('Hello,測試顏色例子') layout.addWidget(self.colorLabel) self.setLayout(layout) def getColor(self): color = QColorDialog.getColor() p = QPalette() p.setColor(QPalette.WindowText, color) self.colorLabel.setPalette(p) def getBGColor(self): color = QColorDialog.getColor() p = QPalette() p.setColor(QPalette.Window, color) self.colorLabel.setAutoFillBackground(True) self.colorLabel.setPalette(p) if __name__ == '__main__': app = QApplication(sys.argv) main = QColorDialogDemo() main.show() sys.exit(app.exec_())
文件對話框

''' 文件對話框:QFileDialog ''' import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class QFileDialogDemo(QWidget): def __init__(self): super(QFileDialogDemo, self).__init__() self.initUI() def initUI(self): layout = QVBoxLayout() self.button1 = QPushButton('加載圖片') self.button1.clicked.connect(self.loadImage) layout.addWidget(self.button1) self.imageLabel = QLabel() layout.addWidget(self.imageLabel) self.button2 = QPushButton('加載文本文件') self.button2.clicked.connect(self.loadText) layout.addWidget(self.button2) self.contents = QTextEdit() layout.addWidget(self.contents) self.setLayout(layout) self.setWindowTitle('文件對話框演示 ') def loadImage(self): fname, _ = QFileDialog.getOpenFileName(self, '打開文件', '.', '圖像文件(*.jpg *.png)') self.imageLabel.setPixmap(QPixmap(fname)) def loadText(self): dialog = QFileDialog() dialog.setFileMode(QFileDialog.AnyFile) dialog.setFilter(QDir.Files) if dialog.exec(): filenames = dialog.selectedFiles() f = open(filenames[0], encoding='utf-8', mode='r') with f: data = f.read() self.contents.setText(data) if __name__ == '__main__': app = QApplication(sys.argv) main = QFileDialogDemo() main.show() sys.exit(app.exec_())
表格與樹
表格控件

''' 顯示二維表數據(QTableView控件) 數據源 Model 需要創建QTableView實例和一個數據源(Model),然后將兩者關聯 MVC:Model Viewer Controller MVC的目的是將后端的數據和前端頁面的耦合度降低 ''' from PyQt5.QtWidgets import * from PyQt5.QtGui import * import sys class TableView(QWidget): def __init__(self, arg=None): super(TableView, self).__init__(arg) self.setWindowTitle("QTableView表格視圖控件演示") self.resize(500, 300) self.model = QStandardItemModel(4, 3) self.model.setHorizontalHeaderLabels(['id', '姓名', '年齡']) self.tableview = QTableView() # 關聯QTableView控件和Model self.tableview.setModel(self.model) # 添加數據 item11 = QStandardItem('10') item12 = QStandardItem('雷神') item13 = QStandardItem('2000') self.model.setItem(0, 0, item11) self.model.setItem(0, 1, item12) self.model.setItem(0, 2, item13) item31 = QStandardItem('30') item32 = QStandardItem('死亡女神') item33 = QStandardItem('3000') self.model.setItem(2, 0, item31) self.model.setItem(2, 1, item32) self.model.setItem(2, 2, item33) layout = QVBoxLayout() layout.addWidget(self.tableview) self.setLayout(layout) if __name__ == '__main__': app = QApplication(sys.argv) table = TableView() table.show() sys.exit(app.exec_())
擴展的表格控件

''' 擴展的表格控件(QTableWidget) QTableView 每一個Cell(單元格)是一個QTableWidgetItem ''' import sys from PyQt5.QtWidgets import (QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem, QAbstractItemView) class TableWidgetDemo(QWidget): def __init__(self): super(TableWidgetDemo, self).__init__() self.initUI() def initUI(self): self.setWindowTitle("QTableWidget演示") self.resize(430, 230); layout = QHBoxLayout() tablewidget = QTableWidget() tablewidget.setRowCount(4) tablewidget.setColumnCount(3) layout.addWidget(tablewidget) tablewidget.setHorizontalHeaderLabels(['姓名', '年齡', '籍貫']) nameItem = QTableWidgetItem("小明") tablewidget.setItem(0, 0, nameItem) ageItem = QTableWidgetItem("24") tablewidget.setItem(0, 1, ageItem) jgItem = QTableWidgetItem("北京") tablewidget.setItem(0, 2, jgItem) # 禁止編輯 tablewidget.setEditTriggers(QAbstractItemView.NoEditTriggers) # 整行選擇 tablewidget.setSelectionBehavior(QAbstractItemView.SelectRows) # 調整列和行 tablewidget.resizeColumnsToContents() tablewidget.resizeRowsToContents() tablewidget.horizontalHeader().setVisible(False) # tablewidget.verticalHeader().setVisible(False) tablewidget.setVerticalHeaderLabels(["a", "b"]) # 隱藏表格線 tablewidget.setShowGrid(False) self.setLayout(layout) if __name__ == '__main__': app = QApplication(sys.argv) example = TableWidgetDemo() example.show() sys.exit(app.exec_())
樹控件

''' 樹控件(QTreeWidget)的基本用法 ''' import sys from PyQt5.QtWidgets import * from PyQt5.QtGui import QIcon, QBrush, QColor from PyQt5.QtCore import Qt class BasicTreeWidget(QMainWindow): def __init__(self, parent=None): super(BasicTreeWidget, self).__init__(parent) self.setWindowTitle('樹控件(QTreeWidget)的基本用法') self.tree = QTreeWidget() # 為樹控件指定列數 self.tree.setColumnCount(2) # 指定列標簽 self.tree.setHeaderLabels(['Key', 'Value']) root = QTreeWidgetItem(self.tree) root.setText(0, '根節點') root.setIcon(0, QIcon('./images/root.png')) self.tree.setColumnWidth(0, 160) # 添加子節點1 child1 = QTreeWidgetItem(root) child1.setText(0, '子節點1') child1.setText(1, '子節點1的數據') child1.setIcon(0, QIcon('./images/bao3.png')) child1.setCheckState(0, Qt.Checked) # 添加子節點2 child2 = QTreeWidgetItem(root) child2.setText(0, '子節點2') child2.setIcon(0, QIcon('./images/bao6.png')) # 為child2添加一個子節點 child3 = QTreeWidgetItem(child2) child3.setText(0, '子節點2-1') child3.setText(1, '新的值') child3.setIcon(0, QIcon('./images/music.png')) self.tree.expandAll() self.setCentralWidget(self.tree) if __name__ == '__main__': app = QApplication(sys.argv) tree = BasicTreeWidget() tree.show() sys.exit(app.exec_())

''' 為樹節點添加響應事件 ''' from PyQt5.QtWidgets import * from PyQt5.QtCore import * import sys class TreeEvent(QMainWindow): def __init__(self, parent=None): super(TreeEvent, self).__init__(parent) self.setWindowTitle('為樹節點添加響應事件') self.tree = QTreeWidget() self.tree.setColumnCount(2) self.tree.setHeaderLabels(['Key', 'Value']) root = QTreeWidgetItem(self.tree) root.setText(0, 'root') root.setText(1, '0') child1 = QTreeWidgetItem(root) child1.setText(0, 'child1') child1.setText(1, '1') child2 = QTreeWidgetItem(root) child2.setText(0, 'child2') child2.setText(1, '2') child3 = QTreeWidgetItem(child2) child3.setText(0, 'child3') child3.setText(1, '3') self.tree.clicked.connect(self.onTreeClicked) self.setCentralWidget(self.tree) def onTreeClicked(self, index): item = self.tree.currentItem() print(index.row()) print('key=%s,value=%s' % (item.text(0), item.text(1))) if __name__ == '__main__': app = QApplication(sys.argv) tree = TreeEvent() tree.show() sys.exit(app.exec_())

''' 添加、修改和刪除樹控件中的節點 ''' import sys from PyQt5.QtWidgets import * class ModifyTree(QWidget): def __init__(self, parent=None): super(ModifyTree, self).__init__(parent) self.setWindowTitle('TreeWidget 例子') operatorLayout = QHBoxLayout() addBtn = QPushButton('添加節點') updateBtn = QPushButton('修改節點') deleteBtn = QPushButton('刪除節點') operatorLayout.addWidget(addBtn) operatorLayout.addWidget(updateBtn) operatorLayout.addWidget(deleteBtn) addBtn.clicked.connect(self.addNode) updateBtn.clicked.connect(self.updateNode) deleteBtn.clicked.connect(self.deleteNode) self.tree = QTreeWidget() self.tree.setColumnCount(2) self.tree.setHeaderLabels(['Key', 'Value']) root = QTreeWidgetItem(self.tree) root.setText(0, 'root') root.setText(1, '0') child1 = QTreeWidgetItem(root) child1.setText(0, 'child1') child1.setText(1, '1') child2 = QTreeWidgetItem(root) child2.setText(0, 'child2') child2.setText(1, '2') child3 = QTreeWidgetItem(child2) child3.setText(0, 'child3') child3.setText(1, '3') self.tree.clicked.connect(self.onTreeClicked) mainLayout = QVBoxLayout(self) mainLayout.addLayout(operatorLayout) mainLayout.addWidget(self.tree) self.setLayout(mainLayout) def onTreeClicked(self, index): item = self.tree.currentItem() print(index.row()) print('key=%s,value=%s' % (item.text(0), item.text(1))) # 添加節點 def addNode(self): print('添加節點') item = self.tree.currentItem() print(item) node = QTreeWidgetItem(item) node.setText(0, '新節點') node.setText(1, '新值') def updateNode(self): print('修改節點') item = self.tree.currentItem() item.setText(0, '修改節點') item.setText(1, '值已經被修改') def deleteNode(self): print('刪除節點') item = self.tree.currentItem() root = self.tree.invisibleRootItem() for item in self.tree.selectedItems(): (item.parent() or root).removeChild(item) if __name__ == '__main__': app = QApplication(sys.argv) tree = ModifyTree() tree.show() sys.exit(app.exec_())
容器控件
QTabWidget

''' 選項卡控件:QTabWidget ''' import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class TabWidgetDemo(QTabWidget): def __init__(self, parent=None): super(TabWidgetDemo, self).__init__(parent) self.setWindowTitle("選項卡控件:QTabWidget") # 創建用於顯示控件的窗口 self.tab1 = QWidget() self.tab2 = QWidget() self.tab3 = QWidget() self.addTab(self.tab1, '選項卡1') self.addTab(self.tab2, '選項卡2') self.addTab(self.tab3, '選項卡3') self.tab1UI() self.tab2UI() self.tab3UI() def tab1UI(self): layout = QFormLayout() layout.addRow('姓名', QLineEdit()) layout.addRow('地址', QLineEdit()) self.setTabText(0, '聯系方式') self.tab1.setLayout(layout) def tab2UI(self): layout = QFormLayout() sex = QHBoxLayout() sex.addWidget(QRadioButton('男')) sex.addWidget(QRadioButton('女')) layout.addRow(QLabel('性別'), sex) layout.addRow('生日', QLineEdit()) self.setTabText(1, '個人詳細信息') self.tab2.setLayout(layout) def tab3UI(self): layout = QHBoxLayout() layout.addWidget(QLabel('科目')) layout.addWidget(QCheckBox('物理')) layout.addWidget(QCheckBox('高數')) self.setTabText(2, '教育程度') self.tab3.setLayout(layout) if __name__ == '__main__': app = QApplication(sys.argv) demo = TabWidgetDemo() demo.show() sys.exit(app.exec_())
QStackedWidget

''' 堆棧窗口控件(QStackedWidget) ''' import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class StackedExample(QWidget): def __init__(self): super(StackedExample, self).__init__() self.setGeometry(300, 50, 10, 10) self.setWindowTitle('堆棧窗口控件(QStackedWidget)') self.list = QListWidget() self.list.insertItem(0,'聯系方式') self.list.insertItem(1,'個人信息') self.list.insertItem(2,'教育程度') self.stack1 = QWidget() self.stack2 = QWidget() self.stack3 = QWidget() self.tab1UI() self.tab2UI() self.tab3UI() self.stack = QStackedWidget() self.stack.addWidget(self.stack1) self.stack.addWidget(self.stack2) self.stack.addWidget(self.stack3) hbox = QHBoxLayout() hbox.addWidget(self.list) hbox.addWidget(self.stack) self.setLayout(hbox) self.list.currentRowChanged.connect(self.display) def tab1UI(self): layout = QFormLayout() layout.addRow('姓名',QLineEdit()) layout.addRow('地址',QLineEdit()) self.stack1.setLayout(layout) def tab2UI(self): layout = QFormLayout() sex = QHBoxLayout() sex.addWidget(QRadioButton('男')) sex.addWidget(QRadioButton('女')) layout.addRow(QLabel('性別'),sex) layout.addRow('生日',QLineEdit()) self.stack2.setLayout(layout) def tab3UI(self): layout = QHBoxLayout() layout.addWidget(QLabel('科目')) layout.addWidget(QCheckBox('物理')) layout.addWidget(QCheckBox('高數')) self.stack3.setLayout(layout) def display(self,index): self.stack.setCurrentIndex(index) if __name__ == '__main__': app = QApplication(sys.argv) demo = StackedExample() demo.show() sys.exit(app.exec_())
QDockWidget

''' 停靠控件(QDockWidget) ''' import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class DockDemo(QMainWindow): def __init__(self, parent=None): super(DockDemo, self).__init__(parent) self.setWindowTitle("停靠控件(QDockWidget)") layout = QHBoxLayout() self.items = QDockWidget('Dockable',self) self.listWidget = QListWidget() self.listWidget.addItem('item1') self.listWidget.addItem('item2') self.listWidget.addItem('item3') self.items.setWidget(self.listWidget) self.setCentralWidget(QLineEdit()) self.items.setFloating(True) # 一開始就處於懸浮狀態 self.addDockWidget(Qt.RightDockWidgetArea,self.items) # 默認停靠在右側 if __name__ == '__main__': app = QApplication(sys.argv) demo = DockDemo() demo.show() sys.exit(app.exec_())
QMdiArea

''' 容納多文檔的窗口 QMdiArea QMdiSubWindow ''' import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class MultiWindows(QMainWindow): count = 0 def __init__(self, parent=None): super(MultiWindows, self).__init__(parent) self.setWindowTitle("容納多文檔的窗口") self.mdi = QMdiArea() self.setCentralWidget(self.mdi) bar = self.menuBar() file = bar.addMenu("File") file.addAction("New") file.addAction("cascade") file.addAction("Tiled") file.triggered.connect(self.windowaction) def windowaction(self,q): print(q.text()) if q.text() == "New": MultiWindows.count = MultiWindows.count + 1 sub = QMdiSubWindow() sub.setWidget(QTextEdit()) sub.setWindowTitle("子窗口" + str(MultiWindows.count)) self.mdi.addSubWindow(sub) sub.show() elif q.text() == "cascade": self.mdi.cascadeSubWindows() elif q.text() == "Tiled": self.mdi.tileSubWindows() if __name__ == '__main__': app = QApplication(sys.argv) demo = MultiWindows() demo.show() sys.exit(app.exec_())
QScrollBar

''' 滾動條控件(QScrollBar) QScrollBar的作用 1. 通過滾動條值的變化控制其他控件狀態的變化 2. 通過滾動條值的變化控制控件位置的變化 ''' import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class ScrollBar(QWidget): def __init__(self): super(ScrollBar, self).__init__() self.initUI() def initUI(self): hbox = QHBoxLayout() self.label = QLabel('拖動滾動條去改變文字顏色') hbox.addWidget(self.label) self.scrollbar1 = QScrollBar() self.scrollbar1.setMaximum(255) self.scrollbar1.sliderMoved.connect(self.sliderMoved) self.scrollbar2 = QScrollBar() self.scrollbar2.setMaximum(255) self.scrollbar2.sliderMoved.connect(self.sliderMoved) self.scrollbar3 = QScrollBar() self.scrollbar3.setMaximum(255) self.scrollbar3.sliderMoved.connect(self.sliderMoved) self.scrollbar4 = QScrollBar() self.scrollbar4.setMaximum(255) self.scrollbar4.sliderMoved.connect(self.sliderMoved1) hbox.addWidget(self.scrollbar1) hbox.addWidget(self.scrollbar2) hbox.addWidget(self.scrollbar3) hbox.addWidget(self.scrollbar4) self.setGeometry(300, 300, 300, 200) self.setLayout(hbox) self.y = self.label.pos().y() def sliderMoved(self): print(self.scrollbar1.value(), self.scrollbar2.value(), self.scrollbar3.value()) palette = QPalette() c = QColor(self.scrollbar1.value(), self.scrollbar2.value(), self.scrollbar3.value(), 255) palette.setColor(QPalette.Foreground, c) self.label.setPalette(palette) def sliderMoved1(self): self.label.move(self.label.x(), self.y + self.scrollbar4.value()) if __name__ == '__main__': app = QApplication(sys.argv) demo = ScrollBar() demo.show() sys.exit(app.exec_())
多線程
QTimer

''' 動態顯示當前時間 QTimer QThread 多線程:用於同時完成多個任務 ''' from PyQt5.QtWidgets import QWidget, QPushButton, QApplication, QListWidget, QGridLayout, QLabel from PyQt5.QtCore import QTimer, QDateTime import sys class ShowTime(QWidget): def __init__(self, parent=None): super(ShowTime, self).__init__(parent) self.setWindowTitle("動態顯示當前時間") self.label = QLabel('顯示當前時間') self.startBtn = QPushButton('開始') self.endBtn = QPushButton('結束') layout = QGridLayout() self.timer = QTimer() self.timer.timeout.connect(self.showTime) layout.addWidget(self.label, 0, 0, 1, 2) layout.addWidget(self.startBtn, 1, 0) layout.addWidget(self.endBtn, 1, 1) self.startBtn.clicked.connect(self.startTimer) self.endBtn.clicked.connect(self.endTimer) self.setLayout(layout) def showTime(self): time = QDateTime.currentDateTime() timeDisplay = time.toString("yyyy-MM-dd hh:mm:ss dddd") self.label.setText(timeDisplay) def startTimer(self): self.timer.start(1000) self.startBtn.setEnabled(False) self.endBtn.setEnabled(True) def endTimer(self): self.timer.stop() self.startBtn.setEnabled(True) self.endBtn.setEnabled(False) if __name__ == "__main__": app = QApplication(sys.argv) form = ShowTime() form.show() sys.exit(app.exec_())
窗口定時關閉 QTimer.singleShot

''' 讓程序定時關閉 QTimer.singleShot ''' import sys from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import * if __name__ == '__main__': app = QApplication(sys.argv) label = QLabel('<font color=red size=140><b>Hello World,窗口在5秒后自動關閉!</b></font>') label.setWindowFlags(Qt.SplashScreen | Qt.FramelessWindowHint) label.show() QTimer.singleShot(5000,app.quit) sys.exit(app.exec_())
自定義多線程QThread

''' 使用線程類(QThread)編寫計數器 QThread def run(self): while True: self.sleep(1) if sec == 5: break; QLCDNumber WorkThread(QThread) 用到自定義信號 ''' import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * sec = 0 class WorkThread(QThread): timer = pyqtSignal() # 每隔1秒發送一次信號 end = pyqtSignal() # 計數完成后發送一次信號 def run(self): while True: self.sleep(1) # 休眠1秒 if sec == 5: self.end.emit() # 發送end信號 break self.timer.emit() # 發送timer信號 class Counter(QWidget): def __init__(self, parent=None): super(Counter, self).__init__(parent) self.setWindowTitle("使用線程類(QThread)編寫計數器") self.resize(300, 120) layout = QVBoxLayout() self.lcdNumber = QLCDNumber() layout.addWidget(self.lcdNumber) button = QPushButton('開始計數') layout.addWidget(button) self.workThread = WorkThread() # 創建線程 self.workThread.timer.connect(self.countTime) # 連接信號,則觸發函數countTime self.workThread.end.connect(self.end) # 連接信號,則觸發函數end button.clicked.connect(self.work) # 開始線程 self.setLayout(layout) def countTime(self): global sec sec += 1 self.lcdNumber.display(sec) def end(self): QMessageBox.information(self, '消息', '計數結束', QMessageBox.Ok) def work(self): self.workThread.start() if __name__ == "__main__": app = QApplication(sys.argv) form = Counter() form.show() sys.exit(app.exec_())
web交互
瀏覽器控件

'''
用Web瀏覽器控件(QWebEngineView)顯示網頁
PyQt5和Web的交互技術
同時使用Python和Web開發程序,混合開發
Python+JavaScript+HTML5+CSS
QWebEngineView
'''
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import sys
class WebEngineView(QMainWindow):
def __init__(self ):
super(WebEngineView, self).__init__()
self.setWindowTitle('打開外部網頁例子')
self.setGeometry(5, 30, 1355, 730)
self.browser = QWebEngineView()
self.browser.load(QUrl('https://www.jd.com'))
self.setCentralWidget(self.browser)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = WebEngineView()
win.show()
sys.exit(app.exec_())

'''
裝載本地Web頁面
'''
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import sys
import os
class WebEngineView(QMainWindow):
def __init__(self ):
super(WebEngineView, self).__init__()
self.setWindowTitle('裝載本地Web頁面')
self.setGeometry(5, 30, 1355, 730)
url = os.getcwd() + '/test.html'
self.browser = QWebEngineView()
self.browser.load(QUrl.fromLocalFile(url))
self.setCentralWidget(self.browser)
print(os.getcwd())
if __name__ == '__main__':
app = QApplication(sys.argv)
win = WebEngineView()
win.show()
sys.exit(app.exec_())
python與JS交互

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>測試頁面</title> <script> function fullname(value) { alert("<" + value +">") var firstname = document.getElementById('firstname').value; var lastname = document.getElementById('lastname').value; var fullname = firstname + ' ' + lastname; document.getElementById('fullname').value = fullname; document.getElementById('submit-btn').style.display = 'block'; return fullname; } </script> </head> <body> <form> <label>First Name:</label> <input type="text" name="firstname" id="firstname"></input> <br/> <label>Last Name:</label> <input type="text" name="lastname" id="lastname"></input> <br/> <label>Full Name:</label> <input type="text" name="fullname" id="fullname"></input> <br/> <input style="display:none;" type="submit" id="submit-btn" /> </form> </body> </html>

''' PyQt5調用JavaScript代碼 PyQt5和JavaScript交互 什么叫交互 PyQt5 <-> JavaScript ''' from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtWebEngineWidgets import * import sys import os class PyQtCallJS(QWidget): def __init__(self): super(PyQtCallJS, self).__init__() self.setWindowTitle('PyQt5調用JavaScript') self.setGeometry(5, 30, 1355, 730) self.layout = QVBoxLayout() self.setLayout(self.layout) self.browser = QWebEngineView() url = os.getcwd() + '/tt.html' self.browser.load(QUrl.fromLocalFile(url)) self.layout.addWidget(self.browser) button = QPushButton('設置全名') button.clicked.connect(self.fullname) self.layout.addWidget(button) def js_callback(self, result): print(result) def fullname(self): self.value = 'hello world' self.browser.page().runJavaScript('fullname("' + self.value + '");', self.js_callback) if __name__ == '__main__': app = QApplication(sys.argv) win = PyQtCallJS() win.show() sys.exit(app.exec_())
布局

'''
絕對布局
'''
import sys, math
from PyQt5.QtWidgets import *
class AbsoluteLayout(QWidget):
def __init__(self):
super(AbsoluteLayout, self).__init__()
self.setWindowTitle("絕對布局")
self.label1 = QLabel('歡迎', self)
self.label1.move(15, 20)
self.label2 = QLabel('學習', self)
self.label2.move(35, 40)
self.label3 = QLabel('PyQt5', self)
self.label3.move(55, 80)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = AbsoluteLayout()
main.show()
sys.exit(app.exec_())

''' 水平盒布局(QHBoxLayout) ''' import sys, math from PyQt5.QtWidgets import * class HBoxLayout(QWidget): def __init__(self): super(HBoxLayout, self).__init__() self.setWindowTitle("水平盒布局") hlayout = QHBoxLayout() hlayout.addWidget(QPushButton('按鈕1')) hlayout.addWidget(QPushButton('按鈕2')) hlayout.addWidget(QPushButton('按鈕3')) hlayout.addWidget(QPushButton('按鈕4')) hlayout.addWidget(QPushButton('按鈕5')) hlayout.setSpacing(40) self.setLayout(hlayout) if __name__ == '__main__': app = QApplication(sys.argv) main = HBoxLayout() main.show() sys.exit(app.exec_())

''' 設置控件的對齊方式 ''' import sys,math from PyQt5.QtWidgets import * from PyQt5.QtCore import Qt class HBoxLayoutAlign(QWidget) : def __init__(self): super(HBoxLayoutAlign,self).__init__() self.setWindowTitle("水平盒布局") hlayout = QHBoxLayout() hlayout.addWidget(QPushButton('按鈕1'),2,Qt.AlignLeft | Qt.AlignTop) hlayout.addWidget(QPushButton('按鈕2'),4,Qt.AlignLeft | Qt.AlignTop) hlayout.addWidget(QPushButton('按鈕3'),1,Qt.AlignLeft | Qt.AlignTop) hlayout.addWidget(QPushButton('按鈕4'),1,Qt.AlignLeft | Qt.AlignBottom) hlayout.addWidget(QPushButton('按鈕5'),1,Qt.AlignLeft | Qt.AlignBottom) hlayout.setSpacing(40) self.setLayout(hlayout) if __name__ == '__main__': app = QApplication(sys.argv) main = HBoxLayoutAlign() main.show() sys.exit(app.exec_())

''' 設置伸縮量(addStretch) ''' import sys,math from PyQt5.QtWidgets import * class Stretch(QWidget) : def __init__(self): super(Stretch,self).__init__() self.setWindowTitle("設置伸縮量") btn1 = QPushButton(self) btn2 = QPushButton(self) btn3 = QPushButton(self) btn1.setText("按鈕1") btn2.setText("按鈕2") btn3.setText("按鈕3") layout = QHBoxLayout() layout.addStretch(1) layout.addWidget(btn1) layout.addStretch(2) layout.addWidget(btn2) layout.addStretch(3) layout.addWidget(btn3) self.setLayout(layout) if __name__ == '__main__': app = QApplication(sys.argv) main = Stretch() main.show() sys.exit(app.exec_())

''' 設置伸縮量(addStretch) ''' import sys,math from PyQt5.QtWidgets import * class Stretch(QWidget) : def __init__(self): super(Stretch,self).__init__() self.setWindowTitle("設置伸縮量") self.resize(800,100) btn1 = QPushButton(self) btn2 = QPushButton(self) btn3 = QPushButton(self) btn4 = QPushButton(self) btn5 = QPushButton(self) btn1.setText("按鈕1") btn2.setText("按鈕2") btn3.setText("按鈕3") btn4.setText("按鈕4") btn5.setText("按鈕5") layout = QHBoxLayout() layout.addStretch(0) layout.addWidget(btn1) layout.addWidget(btn2) layout.addWidget(btn3) layout.addWidget(btn4) layout.addWidget(btn5) btnOK = QPushButton(self) btnOK.setText("確定") btnCancel = QPushButton(self) btnCancel.setText("取消") layout.addStretch(1) layout.addWidget(btnOK) layout.addWidget(btnCancel) self.setLayout(layout) if __name__ == '__main__': app = QApplication(sys.argv) main = Stretch() main.show() sys.exit(app.exec_())

''' 讓按鈕永遠在窗口右下角 ''' import sys,math from PyQt5.QtWidgets import * from PyQt5.QtCore import Qt class RightBottomButton(QWidget) : def __init__(self): super(RightBottomButton,self).__init__() self.setWindowTitle("讓按鈕永遠在右下角") self.resize(400,300) okButton = QPushButton("確定") cancelButton = QPushButton("取消") hbox = QHBoxLayout() hbox.addStretch(1) hbox.addWidget(okButton) hbox.addWidget(cancelButton) vbox = QVBoxLayout() btn1 = QPushButton("按鈕1") btn2 = QPushButton("按鈕2") btn3 = QPushButton("按鈕3") vbox.addStretch(0) vbox.addWidget(btn1) vbox.addWidget(btn2) vbox.addWidget(btn3) vbox.addStretch(1) vbox.addLayout(hbox) self.setLayout(vbox) if __name__ == '__main__': app = QApplication(sys.argv) main = RightBottomButton() main.show() sys.exit(app.exec_())

''' 垂直盒布局(QBoxLayout) ''' import sys, math from PyQt5.QtWidgets import * class VBoxLayout(QWidget): def __init__(self): super(VBoxLayout, self).__init__() self.setWindowTitle("垂直盒布局") layout = QVBoxLayout() layout.addWidget(QPushButton('按鈕1')) layout.addWidget(QPushButton('按鈕2')) layout.addWidget(QPushButton('按鈕3')) layout.addWidget(QPushButton('按鈕4')) layout.addWidget(QPushButton('按鈕5')) self.setLayout(layout) if __name__ == '__main__': app = QApplication(sys.argv) main = VBoxLayout() main.show() sys.exit(app.exec_())

''' 柵格布局:實現計算器UI ''' import sys, math from PyQt5.QtWidgets import * class Calc(QWidget): def __init__(self): super(Calc, self).__init__() self.setWindowTitle("柵格布局") grid = QGridLayout() self.setLayout(grid) names = ['Cls', 'Back', '', 'Close', '7', '8', '9', '/', '4', '5', '6', '*', '1', '2', '3', '-', '0', '.', '=', '+'] positions = [(i, j) for i in range(5) for j in range(4)] print(positions) for position, name in zip(positions, names): if name == '': continue button = QPushButton(name) # print(position) grid.addWidget(button, *position) if __name__ == '__main__': app = QApplication(sys.argv) main = Calc() main.show() sys.exit(app.exec_())

''' 柵格布局:表單設計 ''' import sys,math from PyQt5.QtWidgets import * class GridForm(QWidget) : def __init__(self): super(GridForm,self).__init__() self.setWindowTitle("柵格布局:表單設計") titleLabel = QLabel('標題') authorLabel = QLabel('作者') contentLabel = QLabel('內容') titleEdit = QLineEdit() authorEdit = QLineEdit() contentEdit = QTextEdit() grid = QGridLayout() grid.setSpacing(10) grid.addWidget(titleLabel,1,0) grid.addWidget(titleEdit,1,1) grid.addWidget(authorLabel,2,0) grid.addWidget(authorEdit,2,1) grid.addWidget(contentLabel,3,0) grid.addWidget(contentEdit,3,1,5,1) self.setLayout(grid) self.resize(350,300) if __name__ == '__main__': app = QApplication(sys.argv) main = GridForm() main.show() sys.exit(app.exec_())

''' 表單布局(QFormLayout) ''' import sys,math from PyQt5.QtWidgets import * class FormForm(QWidget) : def __init__(self): super(FormForm,self).__init__() self.setWindowTitle("表單布局") self.resize(350,300) formLayout = QFormLayout() titleLabel = QLabel('標題') authorLabel = QLabel('作者') contentLabel = QLabel('內容') titleEdit = QLineEdit() authorEdit = QLineEdit() contentEdit = QTextEdit() formLayout.addRow(titleLabel,titleEdit) formLayout.addRow(authorLabel,authorEdit) formLayout.addRow(contentLabel,contentEdit) self.setLayout(formLayout) if __name__ == '__main__': app = QApplication(sys.argv) main = FormForm() main.show() sys.exit(app.exec_())

''' 拖動控件之間的邊界(QSplitter) ''' import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class Splitter(QWidget): def __init__(self): super(Splitter, self).__init__() self.initUI() def initUI(self): hbox = QHBoxLayout(self) self.setWindowTitle('QSplitter 例子') self.setGeometry(300, 300, 300, 200) topleft = QFrame() topleft.setFrameShape(QFrame.StyledPanel) bottom = QFrame() bottom.setFrameShape(QFrame.StyledPanel) splitter1 = QSplitter(Qt.Horizontal) textedit = QTextEdit() splitter1.addWidget(topleft) splitter1.addWidget(textedit) splitter1.setSizes([200,100]) splitter2 = QSplitter(Qt.Vertical) splitter2.addWidget(splitter1) splitter2.addWidget(bottom) hbox.addWidget(splitter2) self.setLayout(hbox) if __name__ == '__main__': app = QApplication(sys.argv) demo = Splitter() demo.show() sys.exit(app.exec_())
信號槽

''' 信號(Signal)與槽(Slot) ''' from PyQt5.QtWidgets import * import sys class SigalSlotDemo(QWidget): def __init__(self): super(SigalSlotDemo, self).__init__() self.initUI() def onClick(self): self.btn.setText("信號已經發出") self.btn.setStyleSheet("QPushButton(max-width:200px;min-width:200px") def initUI(self): self.setGeometry(300, 300, 500, 400) self.setWindowTitle('信號(Signal)與槽(Slot)') self.btn = QPushButton('我的按鈕', self) self.btn.clicked.connect(self.onClick) if __name__ == '__main__': app = QApplication(sys.argv) gui = SigalSlotDemo() gui.show() sys.exit(app.exec_())

''' 自定義信號 pyqtSignal() ''' from PyQt5.QtCore import * class MyTypeSignal(QObject): # 定義一個信號 sendmsg = pyqtSignal(object) # 發送3個參數的信號 sendmsg1 = pyqtSignal(str, int, int) def run(self): self.sendmsg.emit('Hello PyQt5') # 發回的數據 def run1(self): self.sendmsg1.emit("hello", 3, 4) # 發回的數據 class MySlot(QObject): def get(self, msg): print("信息:" + msg) def get1(self, msg, a, b): print(msg) print(a + b) if __name__ == '__main__': send = MyTypeSignal() slot = MySlot() send.sendmsg.connect(slot.get) send.sendmsg1.connect(slot.get1) send.run() send.run1() send.sendmsg.disconnect(slot.get) send.run()

''' 信號與槽自動連接 on_objectname_signalname on_okButton_clicked ''' from PyQt5 import QtCore from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton import sys class AutoSignalSlot(QWidget): def __init__(self): super(AutoSignalSlot, self).__init__() self.okButton = QPushButton("ok", self) self.okButton.setObjectName("okButton") # 1. self.okButton1 = QPushButton("cancel", self) self.okButton1.setObjectName("cancelButton") layout = QHBoxLayout() layout.addWidget(self.okButton) self.setLayout(layout) QtCore.QMetaObject.connectSlotsByName(self) # 2. # self.okButton.clicked.connect(self.on_okButton_clicked) @QtCore.pyqtSlot() def on_okButton_clicked(self): # 2. print("點擊了ok按鈕") @QtCore.pyqtSlot() def on_cancelButton_clicked(self): print("點擊了cancel按鈕") if __name__ == '__main__': app = QApplication(sys.argv) example = AutoSignalSlot() example.show() sys.exit(app.exec_())

''' 使用Lambda表達式為槽函數傳遞參數 Lambda表達式:匿名函數,也就是沒有名字的函數 fun = lambda :print("hello world") fun() fun1 = lambda x,y:print(x,y) fun1("a","b") ''' from PyQt5.QtWidgets import * import sys class LambdaSlotArg(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("使用Lambda表達式為槽函數傳遞參數") button1 = QPushButton("按鈕1") button2 = QPushButton("按鈕2") ok = 100 button1.clicked.connect(lambda :self.onButtonClick(10,ok)) button2.clicked.connect(lambda :self.onButtonClick(ok,-20)) button1.clicked.connect(lambda :QMessageBox.information(self,"結果","單擊了button1")) layout = QHBoxLayout() layout.addWidget(button1) layout.addWidget(button2) mainFrame = QWidget() mainFrame.setLayout(layout) self.setCentralWidget(mainFrame) def onButtonClick(self,m,n): print("m + n =",m + n ) QMessageBox.information(self,"結果",str(m+n)) if __name__ == "__main__": app = QApplication(sys.argv) form = LambdaSlotArg() form.show() sys.exit(app.exec_())

''' 使用Partial對象為槽函數傳遞參數 ''' from PyQt5.QtWidgets import * import sys from functools import partial class PartialSlotArg(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("使用Partial表達式為槽函數傳遞參數") button1 = QPushButton("按鈕1") button2 = QPushButton("按鈕2") x = 20 y = -123 button1.clicked.connect(partial(self.onButtonClick,10,20)) button2.clicked.connect(partial(self.onButtonClick, x, y)) layout = QHBoxLayout() layout.addWidget(button1) layout.addWidget(button2) mainFrame = QWidget() mainFrame.setLayout(layout) self.setCentralWidget(mainFrame) def onButtonClick(self,m,n): print("m + n =",m + n ) QMessageBox.information(self,"結果",str(m+n)) if __name__ == "__main__": app = QApplication(sys.argv) form = PartialSlotArg() form.show() sys.exit(app.exec_())

''' Override(覆蓋)槽函數 ''' from PyQt5.QtWidgets import * from PyQt5.QtCore import * import sys class OverrideSlot(QWidget): def __init__(self): super().__init__() self.setWindowTitle("Override(覆蓋)槽函數") def keyPressEvent(self, e): # 覆蓋 if e.key() == Qt.Key_Escape: self.close() elif e.key() == Qt.Key_Alt: self.setWindowTitle("按下Alt鍵") if __name__ == "__main__": app = QApplication(sys.argv) form = OverrideSlot() form.show() sys.exit(app.exec_())
操作數據庫

''' 操作SQLite數據庫 ''' import sys from PyQt5.QtSql import QSqlDatabase, QSqlQuery def createDB(): db = QSqlDatabase.addDatabase('QSQLITE') # 指定SQLite數據庫的文件名 db.setDatabaseName('./db/database.db') if not db.open(): print('無法建立與數據庫的連接') return False query = QSqlQuery() query.exec('create table people(id int primary key,name varchar(10),address varchar(50))') query.exec('insert into people values(1,"李寧","Shenyang")') query.exec('insert into people values(2,"超人","克星")') db.close() return True if __name__ == '__main__': createDB()

''' 使用可視化的方式對SQLite數據庫進行增、刪、改、查操作 QTableView QSqlTableModel ''' import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtSql import * def initializeModel(model): model.setTable('people') model.setEditStrategy(QSqlTableModel.OnFieldChange) model.select() model.setHeaderData(0, Qt.Horizontal,'ID') model.setHeaderData(1, Qt.Horizontal, '姓名') model.setHeaderData(2, Qt.Horizontal, '地址') def createView(title,model): view = QTableView() view.setModel(model) view.setWindowTitle(title) return view def findrow(i): delrow = i.row() print('del row=%s' % str(delrow)) def addrow(): ret = model.insertRows(model.rowCount(),1) print('insertRow=%s' % str(ret)) if __name__ == '__main__': app = QApplication(sys.argv) db = QSqlDatabase.addDatabase('QSQLITE') db.setDatabaseName('./db/database.db') model = QSqlTableModel() delrow = -1 initializeModel(model) view = createView("展示數據",model) view.clicked.connect(findrow) dlg = QDialog() layout = QVBoxLayout() layout.addWidget(view) addBtn = QPushButton('添加一行') addBtn.clicked.connect(addrow) delBtn = QPushButton('刪除一行') delBtn.clicked.connect(lambda :model.removeRow(view.currentIndex().row())) layout.addWidget(view) layout.addWidget(addBtn) layout.addWidget(delBtn) dlg.setLayout(layout) dlg.setWindowTitle("Database Demo") dlg.resize(500,400) dlg.show() sys.exit(app.exec())

''' 分頁顯示數據 limit n,m limit 10,20 ''' import sys import re from PyQt5.QtWidgets import * from PyQt5.QtCore import Qt from PyQt5.QtSql import * class DataGrid(QWidget): def createTableAndInit(self): # 添加數據庫 self.db = QSqlDatabase.addDatabase('QSQLITE') # 設置數據庫名稱 self.db.setDatabaseName('./db/database.db') # 判斷是否打開 if not self.db.open(): return False # 聲明數據庫查詢對象 query = QSqlQuery() # 創建表 query.exec("create table student(id int primary key, name vchar, sex vchar, age int, deparment vchar)") # 添加記錄 query.exec("insert into student values(1,'張三1','男',20,'計算機')") query.exec("insert into student values(2,'李四1','男',19,'經管')") query.exec("insert into student values(3,'王五1','男',22,'機械')") query.exec("insert into student values(4,'趙六1','男',21,'法律')") query.exec("insert into student values(5,'小明1','男',20,'英語')") query.exec("insert into student values(6,'小李1','女',19,'計算機')") query.exec("insert into student values(7,'小張1','男',20,'機械')") query.exec("insert into student values(8,'小剛1','男',19,'經管')") query.exec("insert into student values(9,'張三2','男',21,'計算機')") query.exec("insert into student values(10,'張三3','女',20,'法律')") query.exec("insert into student values(11,'王五2','男',19,'經管')") query.exec("insert into student values(12,'張三4','男',20,'計算機')") query.exec("insert into student values(13,'小李2','男',20,'機械')") query.exec("insert into student values(14,'李四2','女',19,'經管')") query.exec("insert into student values(15,'趙六3','男',21,'英語')") query.exec("insert into student values(16,'李四2','男',19,'法律')") query.exec("insert into student values(17,'小張2','女',22,'經管')") query.exec("insert into student values(18,'李四3','男',21,'英語')") query.exec("insert into student values(19,'小李3','女',19,'法律')") query.exec("insert into student values(20,'王五3','女',20,'機械')") query.exec("insert into student values(21,'張三4','男',22,'計算機')") query.exec("insert into student values(22,'小李2','男',20,'法律')") query.exec("insert into student values(23,'張三5','男',19,'經管')") query.exec("insert into student values(24,'小張3','女',20,'計算機')") query.exec("insert into student values(25,'李四4','男',22,'英語')") query.exec("insert into student values(26,'趙六2','男',20,'機械')") query.exec("insert into student values(27,'小李3','女',19,'英語')") query.exec("insert into student values(28,'王五4','男',21,'經管')") return True def __init__(self): super().__init__() self.setWindowTitle("分頁查詢例子") self.resize(750, 300) self.createTableAndInit() # 當前頁 self.currentPage = 0 # 總頁數 self.totalPage = 0 # 總記錄數 self.totalRecrodCount = 0 # 每頁顯示記錄數 self.PageRecordCount = 6 self.initUI() def initUI(self): # 創建窗口 self.createWindow() # 設置表格 self.setTableView() # 信號槽連接 self.prevButton.clicked.connect(self.onPrevButtonClick) self.nextButton.clicked.connect(self.onNextButtonClick) self.switchPageButton.clicked.connect(self.onSwitchPageButtonClick) def closeEvent(self, event): # 關閉數據庫 self.db.close() # 創建窗口 def createWindow(self): # 操作布局 operatorLayout = QHBoxLayout() self.prevButton = QPushButton("前一頁") self.nextButton = QPushButton("后一頁") self.switchPageButton = QPushButton("Go") self.switchPageLineEdit = QLineEdit() self.switchPageLineEdit.setFixedWidth(40) switchPage = QLabel("轉到第") page = QLabel("頁") operatorLayout.addWidget(self.prevButton) operatorLayout.addWidget(self.nextButton) operatorLayout.addWidget(switchPage) operatorLayout.addWidget(self.switchPageLineEdit) operatorLayout.addWidget(page) operatorLayout.addWidget(self.switchPageButton) operatorLayout.addWidget(QSplitter()) # 狀態布局 statusLayout = QHBoxLayout() self.totalPageLabel = QLabel() self.totalPageLabel.setFixedWidth(70) self.currentPageLabel = QLabel() self.currentPageLabel.setFixedWidth(70) self.totalRecordLabel = QLabel() self.totalRecordLabel.setFixedWidth(70) statusLayout.addWidget(self.totalPageLabel) statusLayout.addWidget(self.currentPageLabel) statusLayout.addWidget(QSplitter()) statusLayout.addWidget(self.totalRecordLabel) # 設置表格屬性 self.tableView = QTableView() # 表格寬度的自適應調整 self.tableView.horizontalHeader().setStretchLastSection(True) self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # 創建界面 mainLayout = QVBoxLayout(self) mainLayout.addLayout(operatorLayout) mainLayout.addWidget(self.tableView) mainLayout.addLayout(statusLayout) self.setLayout(mainLayout) # 設置表格 def setTableView(self): # 聲明查詢模型 self.queryModel = QSqlQueryModel(self) # 設置當前頁 self.currentPage = 1 # 得到總記錄數 self.totalRecrodCount = self.getTotalRecordCount() # 得到總頁數 self.totalPage = self.getPageCount() # 刷新狀態 self.updateStatus() # 設置總頁數文本 self.setTotalPageLabel() # 設置總記錄數 self.setTotalRecordLabel() # 記錄查詢 self.recordQuery(0) # 設置模型 self.tableView.setModel(self.queryModel) print('totalRecrodCount=' + str(self.totalRecrodCount)) print('totalPage=' + str(self.totalPage)) # 設置表格表頭 self.queryModel.setHeaderData(0, Qt.Horizontal, "編號") self.queryModel.setHeaderData(1, Qt.Horizontal, "姓名") self.queryModel.setHeaderData(2, Qt.Horizontal, "性別") self.queryModel.setHeaderData(3, Qt.Horizontal, "年齡") self.queryModel.setHeaderData(4, Qt.Horizontal, "院系") # 得到記錄數 def getTotalRecordCount(self): self.queryModel.setQuery("select * from student") rowCount = self.queryModel.rowCount() print('rowCount=' + str(rowCount)) return rowCount # 得到頁數 def getPageCount(self): if self.totalRecrodCount % self.PageRecordCount == 0: return (self.totalRecrodCount / self.PageRecordCount) else: return (self.totalRecrodCount / self.PageRecordCount + 1) # 記錄查詢 def recordQuery(self, limitIndex): szQuery = ("select * from student limit %d,%d" % (limitIndex, self.PageRecordCount)) print('query sql=' + szQuery) self.queryModel.setQuery(szQuery) # 刷新狀態 def updateStatus(self): szCurrentText = ("當前第%d頁" % self.currentPage) self.currentPageLabel.setText(szCurrentText) # 設置按鈕是否可用 if self.currentPage == 1: self.prevButton.setEnabled(False) self.nextButton.setEnabled(True) elif self.currentPage == self.totalPage: self.prevButton.setEnabled(True) self.nextButton.setEnabled(False) else: self.prevButton.setEnabled(True) self.nextButton.setEnabled(True) # 設置總數頁文本 def setTotalPageLabel(self): szPageCountText = ("總共%d頁" % self.totalPage) self.totalPageLabel.setText(szPageCountText) # 設置總記錄數 def setTotalRecordLabel(self): szTotalRecordText = ("共%d條" % self.totalRecrodCount) print('*** setTotalRecordLabel szTotalRecordText=' + szTotalRecordText) self.totalRecordLabel.setText(szTotalRecordText) # 前一頁按鈕按下 def onPrevButtonClick(self): print('*** onPrevButtonClick ') limitIndex = (self.currentPage - 2) * self.PageRecordCount self.recordQuery(limitIndex) self.currentPage -= 1 self.updateStatus() # 后一頁按鈕按下 def onNextButtonClick(self): print('*** onNextButtonClick ') limitIndex = self.currentPage * self.PageRecordCount self.recordQuery(limitIndex) self.currentPage += 1 self.updateStatus() # 轉到頁按鈕按下 def onSwitchPageButtonClick(self): # 得到輸入字符串 szText = self.switchPageLineEdit.text() # 得到頁數 pageIndex = int(szText) # 判斷是否有指定頁 if pageIndex > self.totalPage or pageIndex < 1: QMessageBox.information(self, "提示", "沒有指定的頁面,請重新輸入") return # 得到查詢起始行號 limitIndex = (pageIndex - 1) * self.PageRecordCount # 記錄查詢 self.recordQuery(limitIndex) # 設置當前頁 self.currentPage = pageIndex # 刷新狀態 self.updateStatus() if __name__ == '__main__': app = QApplication(sys.argv) # 創建窗口 example = DataGrid() # 顯示窗口 example.show() sys.exit(app.exec_())
項目實戰
天氣查詢

# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'WeatherWin.ui' # # Created by: PyQt5 UI code generator 5.9.2 # # WARNING! All changes made in this file will be lost! from PyQt5 import QtCore, QtGui, QtWidgets class Ui_Form(object): def setupUi(self, Form): Form.setObjectName("Form") Form.resize(450, 347) self.groupBox = QtWidgets.QGroupBox(Form) self.groupBox.setGeometry(QtCore.QRect(10, 10, 431, 251)) self.groupBox.setObjectName("groupBox") self.weatherComboBox = QtWidgets.QComboBox(self.groupBox) self.weatherComboBox.setGeometry(QtCore.QRect(60, 30, 131, 21)) self.weatherComboBox.setObjectName("weatherComboBox") self.weatherComboBox.addItem("") self.weatherComboBox.addItem("") self.weatherComboBox.addItem("") self.resultText = QtWidgets.QTextEdit(self.groupBox) self.resultText.setGeometry(QtCore.QRect(10, 60, 411, 181)) self.resultText.setObjectName("resultText") self.label = QtWidgets.QLabel(self.groupBox) self.label.setGeometry(QtCore.QRect(20, 30, 72, 21)) self.label.setObjectName("label") self.queryBtn = QtWidgets.QPushButton(Form) self.queryBtn.setGeometry(QtCore.QRect(90, 300, 93, 28)) self.queryBtn.setObjectName("queryBtn") self.clearBtn = QtWidgets.QPushButton(Form) self.clearBtn.setGeometry(QtCore.QRect(230, 300, 93, 28)) self.clearBtn.setObjectName("clearBtn") self.retranslateUi(Form) self.clearBtn.clicked.connect(Form.clearResult) self.queryBtn.clicked.connect(Form.queryWeather) QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "Form")) self.groupBox.setTitle(_translate("Form", "查詢城市天氣")) self.weatherComboBox.setItemText(0, _translate("Form", "北京")) self.weatherComboBox.setItemText(1, _translate("Form", "天津")) self.weatherComboBox.setItemText(2, _translate("Form", "上海")) self.label.setText(_translate("Form", "城市")) self.queryBtn.setText(_translate("Form", "查詢")) self.clearBtn.setText(_translate("Form", "清空"))

''' 項目實戰:天氣信息查詢 ''' import sys from PyQt5.QtWidgets import QApplication, QMainWindow from WeatherWin import Ui_Form import requests class MainWindow(QMainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.ui = Ui_Form() self.ui.setupUi(self) def queryWeather(self): cityName = self.ui.weatherComboBox.currentText() cityCode = self.transCityName(cityName) rep = requests.get('http://www.weather.com.cn/data/sk/' + cityCode + '.html') rep.encoding = 'utf-8' print(rep.json()) msg1 = '城市: %s' % rep.json()['weatherinfo']['city'] + '\n' msg2 = '風向: %s' % rep.json()['weatherinfo']['WD'] + '\n' msg3 = '溫度: %s' % rep.json()['weatherinfo']['temp'] + ' 度' + '\n' msg4 = '風力: %s' % rep.json()['weatherinfo']['WS'] + '\n' msg5 = '濕度: %s' % rep.json()['weatherinfo']['SD'] + '\n' result = msg1 + msg2 + msg3 + msg4 + msg5 self.ui.resultText.setText(result) def transCityName(self, cityName): cityCode = '' if cityName == '北京': cityCode = '101010100' elif cityName == '天津': cityCode = '101030100' elif cityName == '上海': cityCode = '101020100' return cityCode def clearResult(self): print('* clearResult ') self.ui.resultText.clear() if __name__ == "__main__": app = QApplication(sys.argv) win = MainWindow() win.show() sys.exit(app.exec_())