0

I have a menu that I created


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None)
    ...
    create_menu_bar()
    ...

    def create_menu_bar(self):
        sheet_one = QtWidgets.QAction("sheet_one", self)
        sheet_one.triggered.connect(lambda: self.load_df(sheet_name="sheet one"))
        # more QActions createad

        menu = self.menuBar()
        menu.addAction(sheet_one)
        # drop down list
        sheet_five_menu = menu.addMenu("&sheet five")
        sheet_five_menu.addAction(sheet_five_one)
        sheet_five_menu.addAction(sheet_five_two)
        ...

I am trying to use pytest-qt to imitate a user clicking on one of the menu options, or clicking on one of the drop down menu options from sheet_five_menu

After reading the documentation I have been able to understand how to open a window and view it. But I am having trouble understanding how to imitate user mouse clicks on my implementation of the menu. I read this stackoverflow, implemented, but got this error.

E AttributeError: 'NoneType' object has no attribute 'triggered'

test_app.py:11: AttributeError

what my test code currently looks like


def test_menu(qtbot):
    window = my_app.MainWindow()
    qtbot.add_widget(window)
    window.show()
    window.findChild(QtWidgets.QAction, 'sheet_one').trigger()


EDIT

reading this qt docs I understand that I should be able to trigger the QAction in this way but I am also getting error

revised code :


window.sheet_one.trigger()

but I am getting this error:

E AttributeError: 'MainWindow' object has no attribute 'sheet_one'

I also tried example:


menu = window.create_menu_bar()
menu.actions()[0]
menu.trigger()

but am getting this error:

E AttributeError: 'NoneType' object has no attribute 'trigger'

Willy
  • 57
  • 7
  • Your latest update is unclear: what does `create_menu_bar` return? – musicamante Jun 28 '23 at 16:01
  • nothing, it is a call to the method to create the menu. I have a lot of different menu options and for my mental sake wanted to move all those creations into a method. – Willy Jun 28 '23 at 16:03
  • If it returns nothing, then `menu.actions()` should have raised the attribute error, which is not what you wrote. And if it returns a menu (as I suspect), then the third line should have been `menu.actions()[0].trigger()`, as the second line is completely useless. – musicamante Jun 28 '23 at 16:10
  • got it thank you. I went with the findChild test instead of menu.actions() – Willy Jun 28 '23 at 16:18

1 Answers1

0

findChild uses the objectName property to find any child QObject.

You are just setting the text, which is mainly a visual clue, but has absolutely no relation with the Qt object name, nor it should ever have any, since the text of an action could change during runtime, and updating the object name based on the text could become a serious problem.

By default QObjects have no object name set (an empty string), so findChild() will return None as there is no QAction that have sheet_one as its objectName.

You also used a space in the text, but you called findChild() using sheet_one with an underscore, so it wouldn't have worked anyway.

Note that if you intended to use that sheet_one as a reference to the variable assigned in create_menu_bar that would be completely pointless, since that is just a local reference and its name is irrelevant; even if you used an instance attribute it wouldn't have worked anyway, because Qt has absolutely no knowledge about python.

Just set the proper object name for the action:

sheet_one.setObjectName('sheet_one')
musicamante
  • 41,230
  • 6
  • 33
  • 58
  • I did this and got this error: E TypeError: native Qt signal is not callable EDIT: forgot to update the testing code. works thank you kind person. – Willy Jun 28 '23 at 16:04
  • @Willy That is not caused by my answer. You probably tried to call `triggered()` (which is a signal, and, as such, not callable) instead of `trigger()`. – musicamante Jun 28 '23 at 16:11
  • that is correct. – Willy Jun 28 '23 at 16:16