PyQt中彈出對話框操作


經常有初學者搞不清楚如何在PyQt中彈出對話框,以及如何處理返回值。這篇文章會舉例說明,界面采用手工編寫。

我們一般說的對話框指的是模態對話框(Modal Dialogue Box),一旦彈出,就不能對話框以外的窗口進行操作,必須先關閉對話框。

在PyQt中我們一般從QDialog繼承創建一個類來操作,根據exec_()方法的返回值判斷用戶是【確定】還是【取消】了,當然也可以其他返回值,具體看文檔。

這個例子創建一個主窗口,有一個表格,記錄用戶姓名和年齡,一個【添加】按鈕,點擊彈出對話框,用戶輸入姓名和年齡,點擊【確定】返回,在主窗體表格中插入一行數據。

創建主窗體

為了方便起見使用QWdiget創建主窗體,當然你可以使用QMainWindow,用QTableView和QStandardItemModel來創建表格。

class MainWindow(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)

# 創建table和model
table = QtGui.QTableView(parent=self)
self.model = QtGui.QStandardItemModel(parent=self)
self.model.setHorizontalHeaderLabels((u'姓名', u'年齡'))
table.setModel(self.model)

# 創建添加按鈕
button = QtGui.QPushButton(u'添加', parent=self)

# 添加信號槽
button.clicked.connect(self.add)

# 創建一個垂直布局,用於防止表格和按鈕
layout = QtGui.QVBoxLayout()
layout.addWidget(table)
layout.addWidget(button)

self.setLayout(layout)

def add(self):
pass
創建對話框

對話框從QDialog繼承,按鈕這里使用QButtonBox來創建,用QButtonBox的好處是創建方便,定義參數即可,並且會自動根據不同平台顯示按鈕的位置,和各平台風格保持一致,當然默認是英文的,你可以通過國際化來做成中文的。

這里沒有做對話框內容的驗證,你可以覆蓋QDialog的accept方法來進行驗證。

下面是對話框的創建代碼,為了方便獲取姓名和年齡變量,我寫了兩個方法供外部調用。

class Dialog(QtGui.QDialog):
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent)
self.resize(240, 200)

# 表格布局,用來布局QLabel和QLineEdit及QSpinBox
grid = QtGui.QGridLayout()

grid.addWidget(QtGui.QLabel(u'姓名', parent=self), 0, 0, 1, 1)

self.leName = QtGui.QLineEdit(parent=self)
grid.addWidget(self.leName, 0, 1, 1, 1)

grid.addWidget(QtGui.QLabel(u'年齡', parent=self), 1, 0, 1, 1)

self.sbAge = QtGui.QSpinBox(parent=self)
grid.addWidget(self.sbAge, 1, 1, 1, 1)

# 創建ButtonBox,用戶確定和取消
buttonBox = QtGui.QDialogButtonBox(parent=self)
buttonBox.setOrientation(QtCore.Qt.Horizontal) # 設置為水平方向
buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) # 確定和取消兩個按鈕
# 連接信號和槽
buttonBox.accepted.connect(self.accept) # 確定
buttonBox.rejected.connect(self.reject) # 取消

# 垂直布局,布局表格及按鈕
layout = QtGui.QVBoxLayout()

# 加入前面創建的表格布局
layout.addLayout(grid)

# 放一個間隔對象美化布局
spacerItem = QtGui.QSpacerItem(20, 48, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
layout.addItem(spacerItem)

# ButtonBox
layout.addWidget(buttonBox)

self.setLayout(layout)

def name(self):
return self.leName.text()

def age(self):
return self.sbAge.value()
編寫對話框調用代碼

調用對話框只要使用exec_方法即可,它會彈出對話框並根據用戶操作返回值,根據返回值判斷是【確定】還是【取消】。

dialog = Dialog(parent=self)
if dialog.exec_():
self.model.appendRow((
QtGui.QStandardItem(dialog.name()),
QtGui.QStandardItem(str(dialog.age())),
))

dialog.destroy()
完整代碼和截圖

# -*- coding: utf-8 -*-
from PyQt4 import QtGui, QtCore

class MainWindow(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)

# 創建table和model
table = QtGui.QTableView(parent=self)
self.model = QtGui.QStandardItemModel(parent=self)
self.model.setHorizontalHeaderLabels((u'姓名', u'年齡'))
table.setModel(self.model)

# 創建添加按鈕
button = QtGui.QPushButton(u'添加', parent=self)

# 添加信號槽
button.clicked.connect(self.add)

# 創建一個垂直布局,用於防止表格和按鈕
layout = QtGui.QVBoxLayout()
layout.addWidget(table)
layout.addWidget(button)

self.setLayout(layout)

def add(self):
dialog = Dialog(parent=self)
if dialog.exec_():
self.model.appendRow((
QtGui.QStandardItem(dialog.name()),
QtGui.QStandardItem(str(dialog.age())),
))

dialog.destroy()


class Dialog(QtGui.QDialog):
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent)
self.resize(240, 200)

# 表格布局,用來布局QLabel和QLineEdit及QSpinBox
grid = QtGui.QGridLayout()

grid.addWidget(QtGui.QLabel(u'姓名', parent=self), 0, 0, 1, 1)

self.leName = QtGui.QLineEdit(parent=self)
grid.addWidget(self.leName, 0, 1, 1, 1)

grid.addWidget(QtGui.QLabel(u'年齡', parent=self), 1, 0, 1, 1)

self.sbAge = QtGui.QSpinBox(parent=self)
grid.addWidget(self.sbAge, 1, 1, 1, 1)

# 創建ButtonBox,用戶確定和取消
buttonBox = QtGui.QDialogButtonBox(parent=self)
buttonBox.setOrientation(QtCore.Qt.Horizontal) # 設置為水平方向
buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) # 確定和取消兩個按鈕
# 連接信號和槽
buttonBox.accepted.connect(self.accept) # 確定
buttonBox.rejected.connect(self.reject) # 取消

# 垂直布局,布局表格及按鈕
layout = QtGui.QVBoxLayout()

# 加入前面創建的表格布局
layout.addLayout(grid)

# 放一個間隔對象美化布局
spacerItem = QtGui.QSpacerItem(20, 48, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
layout.addItem(spacerItem)

# ButtonBox
layout.addWidget(buttonBox)

self.setLayout(layout)

def name(self):
return self.leName.text()

def age(self):
return self.sbAge.value()


if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM