pyqt - 当从另一个 QMainWindow 调用时 QMainWindow 闪烁并消失

标签 pyqt pyside qmainwindow

这段相当简单的代码创建了一个带有三个右键单击选项的系统托盘项。一个是QDialog的实例,另一个是QMainWindow,还有Quit。它适用于系统托盘驱动的应用程序,该应用程序将具有一些 qdialogs 以及一个包含表格小部件的 qmainwindow(或者,是否可以在 qdialog 中创建表格?)。我在这个问题上纠结了一周左右,看了很多相关资料,不明白如何解决。

从系统托盘图标菜单中,单击 QDialog,该对话框将打开,等待用户操作,然后单击“确定”或“取消”按钮将打印所单击的按钮。看起来这可行,因为 QDialog 有它自己的 exec_()。到目前为止非常棒。

但是,单击 QMainWindow 菜单选项,主窗口对话框会短暂出现,然后消失,用户没有机会进行输入。也许相反,qmainwindow 对话框需要依赖于 QApplication 的 exec_() ,其中该对象可能会在 app.exec_() 之前初始化?如果这可行,我不清楚 def qmainwindow() 如何从用户那里检索信息。

希望对于知道的人来说这是一个简单的事情,进行一些更改,宾果游戏。

当前环境:Windows 7 或 XP、Python 2.7、Pyside

如果您运行此程序,系统托盘中将出现一个可单击(右键单击)的空白占位符,或者您也可以为其提供实际图像来代替“sample.png”。

#!python

from PySide       import QtGui, QtCore
from PySide.QtGui import QApplication, QDialog, QMainWindow

def qdialog():
    qdialog_class_obj = TestClassQDialog()
    qdialog_class_obj.show()
    qdialog_class_obj.exec_()    # wait for user

    print "qdialog_user_action: ", qdialog_class_obj.qdialog_user_action

def qmainwindow():
    qmainwindow_class_obj = TestClassQMainWindow()
    qmainwindow_class_obj.show()
    #qmainwindow_class_obj.exec_()  # 'TestClassQMainWindow' object has no attribute 'exec_'

class TestClassQDialog(QDialog):
    def __init__(self, parent=None):    
        super(TestClassQDialog, self).__init__(parent)
        self.ok_cancel = QtGui.QDialogButtonBox(self)
        self.ok_cancel.setStandardButtons(QtGui.QDialogButtonBox.Ok|QtGui.QDialogButtonBox.Cancel)
        QtCore.QObject.connect(self.ok_cancel, QtCore.SIGNAL("accepted()"), self.button_ok)
        QtCore.QObject.connect(self.ok_cancel, QtCore.SIGNAL("rejected()"), self.button_cancel)

    def button_ok(self):
        self.qdialog_user_action = 'ok'
        self.hide()

    def button_cancel(self):
        self.qdialog_user_action = 'cancel'
        self.hide()

class TestClassQMainWindow(QMainWindow):
    def __init__(self, parent=None):    
        super(TestClassQMainWindow, self).__init__(parent)
        self.ok_cancel = QtGui.QDialogButtonBox(self)
        self.ok_cancel.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
        QtCore.QObject.connect(self.ok_cancel, QtCore.SIGNAL("accepted()"), self.button_ok)
        QtCore.QObject.connect(self.ok_cancel, QtCore.SIGNAL("rejected()"), self.button_cancel)

    def button_ok(self):
        self.hide()

    def button_cancel(self):
        self.hide()

class SysTrayIcon(QMainWindow):
    def __init__(self, parent=None):
        super(SysTrayIcon, self).__init__(parent)

        self.qdialog_action     = QtGui.QAction("QDialog",     self, triggered=qdialog)
        self.qmainwindow_action = QtGui.QAction("QMainWindow", self, triggered=qmainwindow)
        self.quit_action        = QtGui.QAction("Quit",        self, triggered=QtGui.qApp.quit)

        self.createSystrayIcon()
        self.systrayIcon.show()

    def createSystrayIcon(self):
        self.systrayIconMenu = QtGui.QMenu(self)
        self.systrayIconMenu.addAction(self.qdialog_action)
        self.systrayIconMenu.addAction(self.qmainwindow_action)
        self.systrayIconMenu.addSeparator()
        self.systrayIconMenu.addAction(self.quit_action)
        self.systrayIcon = QtGui.QSystemTrayIcon(self)
        self.systrayIcon.setContextMenu(self.systrayIconMenu)
        self.systrayIcon.setIcon(QtGui.QIcon('sample.png')) # point to a valid image if you want.
        self.systrayIcon.setVisible(True)

if __name__ == '__main__':
    app = QtGui.QApplication([])
    systrayicon = SysTrayIcon()
    app.exec_()

最佳答案

我已经成功了。我所做的是将您的外部方法 qmainwindow 移到您的内部 SysTrayIcon 并创建了类参数self.qmainwindow_class_obj = TestClassQMainWindow()。我在下面附上了工作代码。另外,您使用的是旧式信号槽方法,我认为您来自老式 PyQt。新方法非常好、干净且Pythonic。我还在下面的代码中添加了新的样式方法。我要做的另一件事是将您的 qdialog 方法移到 SysTrayIcon 类中。我真的不明白为什么你在课外有它,但也许我错过了一些东西。希望这会有所帮助。

#!python

from PySide       import QtGui, QtCore
from PySide.QtGui import QApplication, QDialog, QMainWindow

def qdialog():
    qdialog_class_obj = TestClassQDialog()
    qdialog_class_obj.show()
    qdialog_class_obj.exec_()    # wait for user
    print "qdialog_user_action: ", qdialog_class_obj.qdialog_user_action


class TestClassQDialog(QDialog):
    def __init__(self, parent=None):    
        super(TestClassQDialog, self).__init__(parent)
        self.ok_cancel = QtGui.QDialogButtonBox(self)
        self.ok_cancel.setStandardButtons(QtGui.QDialogButtonBox.Ok|QtGui.QDialogButtonBox.Cancel)        
        self.ok_cancel.accepted.connect(self.button_ok)
        self.ok_cancel.rejected.connect(self.button_cancel)

    def button_ok(self):
        self.qdialog_user_action = 'ok'
        self.hide()

    def button_cancel(self):
        self.qdialog_user_action = 'cancel'
        self.hide()

class TestClassQMainWindow(QMainWindow):
    def __init__(self, parent=None):    
        super(TestClassQMainWindow, self).__init__(parent)
        self.ok_cancel = QtGui.QDialogButtonBox(self)
        self.ok_cancel.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
        self.ok_cancel.accepted.connect(self.button_ok)
        self.ok_cancel.rejected.connect(self.button_cancel)

    def button_ok(self):
        self.hide()

    def button_cancel(self):
        self.hide()

class SysTrayIcon(QMainWindow):
    def __init__(self, parent=None):
        super(SysTrayIcon, self).__init__(parent)

        self.qmainwindow_class_obj = TestClassQMainWindow()

        self.qdialog_action     = QtGui.QAction("QDialog",     self, triggered=qdialog)
        self.qmainwindow_action = QtGui.QAction("QMainWindow", self, triggered=self.qmainwindow)
        self.quit_action        = QtGui.QAction("Quit",        self, triggered=QtGui.qApp.quit)

        self.createSystrayIcon()
        self.systrayIcon.show()

    def createSystrayIcon(self):
        self.systrayIconMenu = QtGui.QMenu(self)
        self.systrayIconMenu.addAction(self.qdialog_action)
        self.systrayIconMenu.addAction(self.qmainwindow_action)
        self.systrayIconMenu.addSeparator()
        self.systrayIconMenu.addAction(self.quit_action)
        self.systrayIcon = QtGui.QSystemTrayIcon(self)
        self.systrayIcon.setContextMenu(self.systrayIconMenu)
        self.systrayIcon.setIcon(QtGui.QIcon('linux.jpeg')) # point to a valid image if you want.
        self.systrayIcon.setVisible(True)

    def qmainwindow(self):
        self.qmainwindow_class_obj.show()


if __name__ == '__main__':
    app = QtGui.QApplication([])
    systrayicon = SysTrayIcon()
    app.exec_()

关于pyqt - 当从另一个 QMainWindow 调用时 QMainWindow 闪烁并消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10183213/

相关文章:

python - 如何更改 QPalette 的当前颜色组

python - 为类似数字代码的系统实现队列

python - PySide:QMetaObject.connectSlotsByName 发出警告 "No matching signal..."但仍然有效..?

python - PyQt5 应用程序中的故障排除(QDialog -> QMainWindow)

c++ - 来自子程序的 QT QMainWindow

python - 如何在不使用类的情况下自动调整 QLabel 像素图保持比率?

python - 如何通过拖动使 PyQt 小部件可调整大小?

qt - 如何让我的 QMainWindow 始终在桌面内?

python - opengl中有没有办法循环旋转二维线

python - Lambda 函数和变量作用域