问题
In a unit test, I'm trying to send the keyboard shortcut Command+N (on Mac OS), which corresponds to a menu item in my app. I'm using the PySide.QtTest module.
In the code below, I'm using QTest.keyClicks
, which doesn't produce what I'm expecting. The action corresponding to the shortcut is not called.
class AppTestCase(TestCase):
def setUp(self):
qApp = QApplication.instance()
if qApp is None:
self.app = QApplication([])
else:
self.app = qApp
class IdfEditorTestCase(th.AppTestCase):
def setUp(self):
super(IdfEditorTestCase, self).setUp()
self.window = IdfEditorWindow()
def test_input_object_in_new_file(self):
if os.path.exists("current_running_test.idf"):
os.remove("current_running_test.idf")
self.window.selectClass("ScheduleTypeLimits")
QTest.keyClicks(self.window, "n", Qt.ControlModifier)
self.window.saveFileAs("current_running_test.idf")
self.assertIdfFileContentEquals("current_running_test.idf", "ScheduleTypeLimits,,,,,;\n")
Some questions:
- Should I send this to the window itself? Or to the menubar? Neither seem to work...
- Is that the right way of sending a keyboard shortcut?
回答1:
For "normal" key-click tests (like entering text in a line-edit), it is not necessary to show the window. This is in line with what you'd expect if you sent key events to a hidden widget during normal running of the application.
But for testing shortcuts, the target window must be shown - which is again in line with what you'd expect. A keyboard shortcut should not activate commands during normal running if the target window is not visible.
So your setup code should probably include something like this:
self.window.show()
QTest.qWaitForWindowShown(self.window)
The qWaitForWindowShown call is necessary on systems where windows are shown asynchronously (for Qt5, use qWaitForWindowExposed).
EDIT:
Here's a test script that works for me:
import unittest
from PySide.QtCore import Qt
from PySide.QtGui import QApplication, QMainWindow, QLineEdit
from PySide.QtTest import QTest
class Window(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
menu = self.menuBar().addMenu('File')
menu.addAction('Test', self.handleTest, 'Ctrl+N')
self.edit = QLineEdit(self)
self.setCentralWidget(self.edit)
def handleTest(self):
self.edit.setText('test')
class AppTestCase(unittest.TestCase):
def setUp(self):
qApp = QApplication.instance()
if qApp is None:
self.app = QApplication([])
else:
self.app = qApp
class WindowTestCase(AppTestCase):
def setUp(self):
super(WindowTestCase, self).setUp()
self.window = Window()
self.window.show()
QTest.qWaitForWindowShown(self.window)
def test_input_object_in_new_file(self):
text = 'test'
self.assertNotEqual(text, self.window.edit.text())
QTest.keyClicks(self.window, 'n', Qt.ControlModifier)
self.assertEqual(text, self.window.edit.text())
def test_enter_text(self):
text = 'foobar'
self.assertNotEqual(text, self.window.edit.text())
QTest.keyClicks(self.window.edit, text)
self.assertEqual(text, self.window.edit.text())
if __name__ == "__main__":
unittest.main()
UPDATE:
Here's a PyQt5 version of the above script:
import unittest
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QMainWindow, QLineEdit
from PyQt5.QtTest import QTest
class Window(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
menu = self.menuBar().addMenu('File')
menu.addAction('Test', self.handleTest, 'Ctrl+N')
self.edit = QLineEdit(self)
self.setCentralWidget(self.edit)
def handleTest(self):
self.edit.setText('test')
class AppTestCase(unittest.TestCase):
def setUp(self):
qApp = QApplication.instance()
if qApp is None:
self.app = QApplication([''])
else:
self.app = qApp
class WindowTestCase(AppTestCase):
def setUp(self):
super(WindowTestCase, self).setUp()
self.window = Window()
self.window.show()
QTest.qWaitForWindowExposed(self.window)
def test_input_object_in_new_file(self):
text = 'test'
self.assertNotEqual(text, self.window.edit.text())
QTest.keyClicks(self.window, 'n', Qt.ControlModifier)
self.assertEqual(text, self.window.edit.text())
def test_enter_text(self):
text = 'foobar'
self.assertNotEqual(text, self.window.edit.text())
QTest.keyClicks(self.window.edit, text)
self.assertEqual(text, self.window.edit.text())
if __name__ == "__main__":
unittest.main()
来源:https://stackoverflow.com/questions/20731054/how-to-send-a-keyboard-shortcut-for-a-menu-item-with-qtest