Pyside2 QAction срабатывает один раз автоматически, но не когда пользователь щелкает меню - PullRequest
0 голосов
/ 04 сентября 2018

Я создал простой графический интерфейс с использованием qt designer и импортировал его в свой проект на python. Появляется главное окно, и меню / кнопки реагируют, но я не могу подключить свои QActions к пользовательским функциям (хотя я сделал это для кнопок, и это работает). Странно то, что моя пользовательская функция (on_action_clicked) вызывается один раз, когда я запускаю приложение, а не когда я нажимаю на пункты меню или значки панели инструментов (я пытался соединить оба). Ниже приведены тестовые коды. Я что-то упустил?

imbrowser3d.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>851</width>
    <height>649</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QGraphicsView" name="gv_image">
    <property name="geometry">
     <rect>
      <x>0</x>
      <y>0</y>
      <width>731</width>
      <height>501</height>
     </rect>
    </property>
   </widget>
   <widget class="QScrollBar" name="sb_index">
    <property name="geometry">
     <rect>
      <x>0</x>
      <y>510</y>
      <width>701</width>
      <height>20</height>
     </rect>
    </property>
    <property name="orientation">
     <enum>Qt::Horizontal</enum>
    </property>
   </widget>
   <widget class="QScrollBar" name="sb_zeta">
    <property name="geometry">
     <rect>
      <x>0</x>
      <y>530</y>
      <width>701</width>
      <height>20</height>
     </rect>
    </property>
    <property name="orientation">
     <enum>Qt::Horizontal</enum>
    </property>
   </widget>
   <widget class="QLabel" name="label_index">
    <property name="geometry">
     <rect>
      <x>700</x>
      <y>510</y>
      <width>55</width>
      <height>16</height>
     </rect>
    </property>
    <property name="text">
     <string>index</string>
    </property>
   </widget>
   <widget class="QLabel" name="label_zeta">
    <property name="geometry">
     <rect>
      <x>700</x>
      <y>530</y>
      <width>55</width>
      <height>16</height>
     </rect>
    </property>
    <property name="text">
     <string>zeta</string>
    </property>
   </widget>
   <widget class="QPushButton" name="pushButton">
    <property name="geometry">
     <rect>
      <x>740</x>
      <y>500</y>
      <width>93</width>
      <height>28</height>
     </rect>
    </property>
    <property name="text">
     <string>PushButton</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>851</width>
     <height>26</height>
    </rect>
   </property>
   <widget class="QMenu" name="menuFile">
    <property name="title">
     <string>File</string>
    </property>
    <addaction name="menu_open"/>
    <addaction name="menu_save"/>
    <addaction name="menu_load"/>
   </widget>
   <addaction name="menuFile"/>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
  <widget class="QToolBar" name="action_toolbar">
   <property name="windowTitle">
    <string>toolBar</string>
   </property>
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
   <addaction name="action_save_state"/>
  </widget>
  <action name="menu_open">
   <property name="text">
    <string>Open</string>
   </property>
  </action>
  <action name="menu_save">
   <property name="icon">
    <iconset>
     <normaloff>ui_icons/save_icon.png</normaloff>ui_icons/save_icon.png</iconset>
   </property>
   <property name="text">
    <string>Save state</string>
   </property>
  </action>
  <action name="menu_load">
   <property name="text">
    <string>Load state</string>
   </property>
  </action>
  <action name="action_save_state">
   <property name="icon">
    <iconset>
     <normaloff>ui_icons/save_icon.png</normaloff>ui_icons/save_icon.png</iconset>
   </property>
   <property name="text">
    <string>Save state</string>
   </property>
   <property name="toolTip">
    <string>Save state</string>
   </property>
  </action>
 </widget>
 <resources/>
 <connections/>
</ui>

main.py

import sys
from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import QApplication, QAction, QPushButton,  QFileDialog
from PySide2.QtCore import QFile, QObject


class UiMainWindow(QObject):

    def __init__(self, ui_file, parent=None):
        super(UiMainWindow, self).__init__(parent)
        ui_file = QFile(ui_file)
        ui_file.open(QFile.ReadOnly)

        loader = QUiLoader()
        self.window = loader.load(ui_file)
        ui_file.close()

        self.btn = self.window.findChild(QPushButton, 'pushButton')
        self.btn.clicked.connect(self.on_btn_clicked)
        self.action_save = self.window.findChild(QAction, 'action_save_state')
        self.action_save.triggered.connect(self.on_action_clicked('action clicked'))
        self.window.show()

    def on_action_clicked(self, txt):
        print(txt)

    def on_btn_clicked():
        print('button clicked')


if __name__ == '__main__':
    app = QApplication(sys.argv)
    form = UiMainWindow('imbrowser3d.ui')
    sys.exit(app.exec_())

1 Ответ

0 голосов
/ 04 сентября 2018

У вас есть 2 ошибки:

  • on_btn_clicked - это метод класса, поэтому он должен иметь в качестве первого параметра экземпляр, то есть self.

  • соединение с именем функции без оценки, в вашем случае слот on_action_clicked вы оцениваете, поэтому вы печатаете его в начале, для него есть 2 возможных решения: использовать частичное или используйте лямбда-функцию.


    self.btn = self.window.findChild(QPushButton, 'pushButton')
    self.btn.clicked.connect(self.on_btn_clicked)
    self.action_save = self.window.findChild(QAction, 'action_save_state')
    self.action_save.triggered.connect(partial(self.on_action_clicked, 'action clicked'))
    # self.action_save.triggered.connect(lambda: self.on_action_clicked('action clicked')) # use lambda function
    self.window.show()

def on_action_clicked(self, txt):
    print(txt)

def on_btn_clicked(self):
    print('button clicked')
...