QT QMessageBox 问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QT QMessageBox 问题相关的知识,希望对你有一定的参考价值。

编译是出现
D:/My Documents/Tetris/widget.cpp:43: error: 'QMessageBox' has not been declared
请大虾们指教啊·咋改··
代码:
QMessageBox::warning(this,tr("warning"),tr("Game Over!"),QMessageBox::Yes); //弹出对话框

代码是没有错,应该是你没有包函库函数引起的,你在widget.cpp里引入这个类就可以了
#include <QMessageBox>
或者直接用
#include <QtGui>
这样就可以了。
参考技术A 错误提示是说QMessageBox未定义,是不是没有包含include<QMessageBox>头文件!本回答被提问者和网友采纳 参考技术B #include <QMessageBox>

如何使用 pytest-qt 点击 QMessageBox?

【中文标题】如何使用 pytest-qt 点击 QMessageBox?【英文标题】:How to click on QMessageBox with pytest-qt? 【发布时间】:2019-12-02 23:02:42 【问题描述】:

我正在使用pytest-qtPyQt 应用程序创建一些单元测试。 我想创建打开图形窗口,做一些测试然后关闭窗口,而不是为每个测试打开一个新窗口,即。对窗口本身使用模块夹具。 我通过调用本地函数 QtBot 而不是使用默认夹具,并删除了嘲笑者,成功地完成了这部分工作。所以我非常接近我的目标。

但是,我无法关闭窗口(并测试 QMessageBox 的关闭事件)。

我喜欢红色的例子 how to handle modal dialog 及其git 讨论,或qmessage 问题;这似乎接近我的问题。 建议使用计时器等待QMessageBox 出现然后单击按钮选项,但显然我无法正确应用它们。 在我的尝试中,pytest 获得了关闭需求,但没有点击dialog 框。所以,我必须点击自己才能完成测试。

这是一个小例子,文件GUI.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys

from PyQt5 import QtGui, QtCore, QtWidgets

from PyQt5.QtWidgets import *
from PyQt5.QtCore import QCoreApplication, Qt, QObject
from PyQt5.QtGui import QIcon


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

    def initUI(self, MainWindow):
        # centralwidget
        MainWindow.resize(346, 193)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        # The Action to quit
        self.toolb_action_Exit = QAction(QIcon('exit.png'), 'Exit', self)
        self.toolb_action_Exit.setShortcut('Ctrl+Q')
        self.toolb_action_Exit.triggered.connect(self.close)

        # The Button
        self.btn_prt = QtWidgets.QPushButton(self.centralwidget)
        self.btn_prt.setGeometry(QtCore.QRect(120, 20, 89, 25))
        self.btn_prt.clicked.connect(lambda: self.doPrint() )
        self.btn_quit = QtWidgets.QPushButton(self.centralwidget)
        self.btn_quit.setGeometry(QtCore.QRect(220, 20, 89, 25))
        self.btn_quit.clicked.connect(lambda: self.close() )

        # The textEdit
        self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
        self.textEdit.setGeometry(QtCore.QRect(10, 60, 321, 81))

        # Show the frame
        MainWindow.setCentralWidget(self.centralwidget)
        self.show()

    def doPrint(self):
        print('TEST doPrint')

    def closeEvent(self, event):
        # Ask a question before to quit.
        self.replyClosing = QMessageBox.question(self, 'Message',
            "Are you sure to quit?", QMessageBox.Yes |
            QMessageBox.No, QMessageBox.No)

        if self.replyClosing == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()


def main_GUI():
    app = QApplication(sys.argv)
    imageViewer = Example()
    return app, imageViewer


if __name__ == '__main__':
    app, imageViewer =main_GUI()
    rc= app.exec_()
    print('App end is exit code '.format(rc))
    sys.exit(rc)

还有名为test_GUI.pypytest文件:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os, sys
import pytest

from PyQt5 import QtGui, QtCore, QtWidgets, QtTest
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QCoreApplication, Qt, QObject

from pytestqt.plugin import QtBot

GUI = __import__('GUI')


@pytest.yield_fixture(scope="module")
def qtbot_session(qapp, request):
    print("  SETUP qtbot")
    result = QtBot(qapp)
    with capture_exceptions() as exceptions:
        yield result
    print("  TEARDOWN qtbot")


@pytest.fixture(scope="module")
def Viewer(request):
    print("  SETUP GUI")
    app, imageViewer = GUI.main_GUI()
    qtbotbis = QtBot(app)
    # qtbotbis.addWidget(imageViewer)
    # qtbotbis.wait_for_window_shown(imageViewer)
    QtTest.QTest.qWait(0.5 *1000)
    yield app, imageViewer, qtbotbis

    # EXIT
    # mocker.patch.object(QMessageBox, 'question', return_value=QMessageBox.Yes)
    # imageViewer.toolb_action_Exit.trigger()
    def handle_dialog():
        # while not imageViewer.replyClosing.isVisible():
        #   app.processEvents()
        box = QMessageBox()
        box.setStandardButtons(QMessageBox.Yes)
        button = box.button(QMessageBox.Yes)
        qtbotbis.mouseClick(button, QtCore.Qt.LeftButton)
    QtCore.QTimer.singleShot(100, handle_dialog)
    qtbotbis.mouseClick(imageViewer.btn_quit, QtCore.Qt.LeftButton, delay=1)
    assert imageViewer.close()
    print("  TEARDOWN GUI")


class Test_GUI() :
    def test_interface(self, Viewer):
        print("  beginning ")
        app, imageViewer, qtbot = Viewer
        qtbot.mouseClick( imageViewer.btn_prt, QtCore.Qt.LeftButton )
        QtTest.QTest.qWait(0.5 *1000)
        assert True
        print(" Test passed")

知道我缺少什么吗?任何其他想法或建议也将不胜感激。

【问题讨论】:

【参考方案1】:

在您的尝试中,您正在创建一个新的QMessageBox,它与使用静态方法QMessageBox::question() 创建的不同,因此即使您单击它也不起作用。

我们的想法是获取显示的QMessageBox,在这种情况下,我们将利用它,因为它是活动窗口,因此我们可以使用QApplication::activeWindow() 获取它。另一种获取QMessageBox的方法是通过findChild()使用imageViewer与QMessageBox的关系:

@pytest.fixture(scope="module")
def Viewer(request):
    print("  SETUP GUI")

    app, imageViewer = GUI.main_GUI()
    qtbotbis = QtBot(app)
    QtTest.QTest.qWait(0.5 * 1000)

    yield app, imageViewer, qtbotbis

    def handle_dialog():
        messagebox = QtWidgets.QApplication.activeWindow()
        # or
        # messagebox = imageViewer.findChild(QtWidgets.QMessageBox)
        yes_button = messagebox.button(QtWidgets.QMessageBox.Yes)
        qtbotbis.mouseClick(yes_button, QtCore.Qt.LeftButton, delay=1)

    QtCore.QTimer.singleShot(100, handle_dialog)
    qtbotbis.mouseClick(imageViewer.btn_quit, QtCore.Qt.LeftButton, delay=1)
    assert imageViewer.isHidden()

【讨论】:

以上是关于QT QMessageBox 问题的主要内容,如果未能解决你的问题,请参考以下文章

QMessageBox消息框的几种类型

Qt 5.1 - QMessageBox 错误?如果在隐藏 QDialog 时调用 QMessageBox,则程序退出(0)

QT QMessageBox 问题

Qt下QMessageBox的问题

qt5---QMessageBox消息框

QT5:QMessageBox