pyqt非模态对话框总是模态的

时间:2016-07-11 14:42:30

标签: python qt pyqt4

我在Qt Designer中设计了一个对话框,并设置为非模态,启动时始终是模态的。我使用的是OS X El Capitan,Python 3.5.1,Qt 5.4.2,pyqt4。

这些代码段显示了我在做什么:

Designer .ui代码使用pyuic转换为python。

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_purchaseInfoDialog(object):
    def setupUi(self, purchaseInfoDialog):
        purchaseInfoDialog.setObjectName(_fromUtf8("purchaseInfoDialog"))
        purchaseInfoDialog.setWindowModality(QtCore.Qt.NonModal)
        purchaseInfoDialog.resize(837, 377)
        purchaseInfoDialog.setSizeGripEnabled(True)
        purchaseInfoDialog.setModal(False)
        self.purchaseInfoButtonBox = QtGui.QDialogButtonBox(purchaseInfoDialog)
        self.purchaseInfoButtonBox.setGeometry(QtCore.QRect(710, 330, 101, 32))
        self.purchaseInfoButtonBox.setOrientation(QtCore.Qt.Horizontal)
        self.purchaseInfoButtonBox.setStandardButtons(QtGui.QDialogButtonBox.Close)
        self.purchaseInfoButtonBox.setObjectName(_fromUtf8("purchaseInfoButtonBox"))
        self.purchaseInfoTable = QtGui.QTableWidget(purchaseInfoDialog)
        self.purchaseInfoTable.setGeometry(QtCore.QRect(10, 50, 911, 271))
        self.purchaseInfoTable.setObjectName(_fromUtf8("purchaseInfoTable"))
        self.purchaseInfoTable.setColumnCount(9)
        self.purchaseInfoTable.setRowCount(0)
        item = QtGui.QTableWidgetItem()
        self.purchaseInfoTable.setHorizontalHeaderItem(0, item)
        item = QtGui.QTableWidgetItem()
        self.purchaseInfoTable.setHorizontalHeaderItem(1, item)
        item = QtGui.QTableWidgetItem()
        self.purchaseInfoTable.setHorizontalHeaderItem(2, item)
        item = QtGui.QTableWidgetItem()
        self.purchaseInfoTable.setHorizontalHeaderItem(3, item)
        item = QtGui.QTableWidgetItem()
        self.purchaseInfoTable.setHorizontalHeaderItem(4, item)
        item = QtGui.QTableWidgetItem()
        self.purchaseInfoTable.setHorizontalHeaderItem(5, item)
        item = QtGui.QTableWidgetItem()
        self.purchaseInfoTable.setHorizontalHeaderItem(6, item)
        item = QtGui.QTableWidgetItem()
        self.purchaseInfoTable.setHorizontalHeaderItem(7, item)
        item = QtGui.QTableWidgetItem()
        self.purchaseInfoTable.setHorizontalHeaderItem(8, item)
        self.piPartLabel = QtGui.QLabel(purchaseInfoDialog)
        self.piPartLabel.setGeometry(QtCore.QRect(20, 20, 71, 16))
        self.piPartLabel.setObjectName(_fromUtf8("piPartLabel"))
        self.piPartdescriptionLabel = QtGui.QLabel(purchaseInfoDialog)
        self.piPartdescriptionLabel.setGeometry(QtCore.QRect(120, 20, 191, 16))
        self.piPartdescriptionLabel.setObjectName(_fromUtf8("piPartdescriptionLabel"))
        self.poFromSelectionPushButton = QtGui.QPushButton(purchaseInfoDialog)
        self.poFromSelectionPushButton.setGeometry(QtCore.QRect(540, 330, 171, 32))
        self.poFromSelectionPushButton.setObjectName(_fromUtf8("poFromSelectionPushButton"))

        self.retranslateUi(purchaseInfoDialog)
        QtCore.QObject.connect(self.purchaseInfoButtonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), purchaseInfoDialog.accept)
        QtCore.QObject.connect(self.purchaseInfoButtonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), purchaseInfoDialog.reject)
        #QtCore.QObject.connect(self.poFromSelectionPushButton, QtCore.SIGNAL(_fromUtf8("clicked()")), purchaseInfoDialog.poFromSelection)
        QtCore.QMetaObject.connectSlotsByName(purchaseInfoDialog)

    def retranslateUi(self, purchaseInfoDialog):
        purchaseInfoDialog.setWindowTitle(_translate("purchaseInfoDialog", "Purchase History", None))
        item = self.purchaseInfoTable.horizontalHeaderItem(0)
        item.setText(_translate("purchaseInfoDialog", "#", None))
        item = self.purchaseInfoTable.horizontalHeaderItem(1)
        item.setText(_translate("purchaseInfoDialog", "P.O. #", None))
        item = self.purchaseInfoTable.horizontalHeaderItem(2)
        item.setText(_translate("purchaseInfoDialog", "Vendor", None))
        item = self.purchaseInfoTable.horizontalHeaderItem(3)
        item.setText(_translate("purchaseInfoDialog", "P.O. Date", None))
        item = self.purchaseInfoTable.horizontalHeaderItem(4)
        item.setText(_translate("purchaseInfoDialog", "Mfg", None))
        item = self.purchaseInfoTable.horizontalHeaderItem(5)
        item.setText(_translate("purchaseInfoDialog", "Mpn", None))
        item = self.purchaseInfoTable.horizontalHeaderItem(6)
        item.setText(_translate("purchaseInfoDialog", "Qty", None))
        item = self.purchaseInfoTable.horizontalHeaderItem(7)
        item.setText(_translate("purchaseInfoDialog", "Price", None))
        item = self.purchaseInfoTable.horizontalHeaderItem(8)
        item.setText(_translate("purchaseInfoDialog", "Dock", None))
        self.piPartLabel.setText(_translate("purchaseInfoDialog", "Part", None))
        self.piPartdescriptionLabel.setText(_translate("purchaseInfoDialog", "Description", None))
        self.poFromSelectionPushButton.setText(_translate("purchaseInfoDialog", "P.O. From Selection", None))

我将设计师类

分类
#
# PURCHASE INFO (HISTORY) Dialog
#
# Sub-class Ui_purchaseInfoDialog
class PurchaseInfoDialog(QDialog, Ui_purchaseInfoDialog):
    def __init__(self):
        QDialog.__init__((self))
        self.setModal(False)

下面的注释代码显示了尝试使其成为非模态的,即使它应该是。什么都行不通。

   self.ui.orderPartButton.clicked.connect(lambda: self.orderPartButtonClicked())

#
# Parts Slots
#
#

@pyqtSlot()
def orderPartButtonClicked(self):
    selectedPart = MainWindow.ui.partShortagesTable.selectedItems()
    if (selectedPart):
        part = selectedPart[0].text()
        aPurchaseInfoDialog = PurchaseInfoDialog()
        pidUi = Ui_purchaseInfoDialog()
        pidUi.setupUi(aPurchaseInfoDialog)

    refreshPurchaseInfoTable(self, pidUi.purchaseInfoTable, pidUi.piPartLabel, pidUi.piPartdescriptionLabel, part, pathToArchive)

    #aPurchaseInfoDialog.setWindowModality(QtCore.Qt.NonModal)
    result = aPurchaseInfoDialog.exec_()  # Launch the Purchase Info Dialog. result = 0 for Close
    #aPurchaseInfoDialog.show()

在我的环境中是否存在pyqt4的问题(我在Linux下尝试了相同的结果)或者我在某个地方错过了一些设置?

演示:

import sys
from PyQt4 import QtCore
from PyQt4.QtCore import *
from PyQt4.QtGui import *



class Dialog1(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.setModal(True)


class Dialog2(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.setModal(False)



def window():
    app = QApplication(sys.argv)
    w = QWidget()
    b = QPushButton(w)
    b.setText("Modal Dialog")
    b.move(15, 25)
    b.clicked.connect(showdialog1)

    c = QPushButton(w)
    c.setText("Modless Dialog")
    c.move(15, 75)
    c.clicked.connect(showdialog2)

    w.setWindowTitle("PyQt Dialog demo")
    w.resize(200, 150)
    w.show()
    sys.exit(app.exec_())


def showdialog1():
    # d = QDialog()
    d = Dialog1()
    #d.setWindowModality(QtCore.Qt.Modal)
    b1 = QPushButton("Modal Dialog", d)
    b1.move(50, 50)
    d.setWindowTitle("Modal Dialog")
    d.setWindowModality(Qt.ApplicationModal)
    d.exec_()

def showdialog2():
    # d = QDialog()
    d = Dialog2()
    d.setWindowModality(QtCore.Qt.NonModal)
    b1 = QPushButton("ok", d)
    b1.move(50, 50)
    d.setWindowTitle("Modeless Dialog")
    d.setWindowModality(Qt.ApplicationModal)
    d.exec_()


if __name__ == '__main__':
    window()

1 个答案:

答案 0 :(得分:3)

由于个人偏好,我重新安排了一些代码(我确定你可以把它放回去没问题),现在一个是模态的,另一个是非模态的。

创建非模态窗口时,必须在QDialog类的实例化中提供父QWidget。然后,使用QDialog.exec_()而不是QDialog.show()。这显示了非模态窗口,但允许原始父级在某种意义上继续运行。使用exec_()将始终生成模态窗口,即使您将其设置为非模态也是如此。这是文档:http://pyqt.sourceforge.net/Docs/PyQt4/qdialog.html

以下是代码:

class Dialog1(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.setModal(True)


class Dialog2(QDialog):
    def __init__(self, parent):
    QDialog.__init__(self, parent)
    self.setModal(0)
    b1 = QPushButton("ok", self)
    b1.move(50, 50)
    b1.clicked.connect(self.exit)
    self.setWindowTitle("Nonmodal Dialog")

    self.show()

def exit(self):
    self.close()


def window():
    app = QApplication(sys.argv)
    w = QWidget()
    b = QPushButton(w)
    b.setText("Modal Dialog")
    b.move(15, 25)
    b.clicked.connect(showdialog1)

    c = QPushButton(w)
    c.setText("Nonmodal Dialog")
    c.move(15, 75)
    c.clicked.connect(lambda: showdialog2(w))

    w.setWindowTitle("PyQt Dialog demo")
    w.resize(200, 150)
    w.show()
    sys.exit(app.exec_())


def showdialog1():
    # d = QDialog()
    d = Dialog1()
    #d.setWindowModality(QtCore.Qt.Modal)
    b1 = QPushButton("Modal Dialog", d)
    b1.move(50, 50)
    d.setWindowTitle("Modal Dialog")
    d.setWindowModality(Qt.ApplicationModal)
    d.exec_()

def showdialog2(w):
    # d = QDialog()
    Dialog2(w)



if __name__ == '__main__':
    window()