使用 PyQT 从第二个表单中捕获按钮方法

Posted

技术标签:

【中文标题】使用 PyQT 从第二个表单中捕获按钮方法【英文标题】:Capturing Button Methods from a second Form using PyQT 【发布时间】:2014-06-18 19:37:32 【问题描述】:

我是 PyQT 的超级新手……我正在为我的表单使用 QT Designer。我对在我的项目中将第二种形式的事件处理放在哪里感到困惑。

我有以下 .py 文件:

main.py Ui_make_render_folders.py(从 Qt 设计器 ui 文件生成) Ui_prefs.py(从 Qt 设计器 ui 文件生成) Mainwindow.py(这是主窗体的所有偶数处理 生活) icons_rc.py(资源文件) make_render_folders.py(我的所有自定义函数都在其中)

这是运行脚本的图片:

click to see script running

我的问题是......我的偏好窗口的均匀处理在哪里????我不知道在哪里将我的 [b]on_btn_released() 放在 y 2nd form 上的按钮。[/b] 另外我不确定我是否正确地实例化了该对话框。目前我正在将此代码添加到我的 MainWindow.py 的顶部。

最后@pyqSignature("") 做了什么?我需要它吗?

"""
This is where all teh MainWindow logic sits
"""
import os
import os.path
from PyQt4.QtGui import QMainWindow,  QFileDialog,  QTreeWidgetItem, QDialog
from PyQt4.QtCore import pyqtSignature,  QString
from make_folders import make_render_folders
from Ui_make_render_folders import Ui_MainWindow
from Ui_prefs import Ui_prefs



class Prefs(QDialog,  Ui_prefs):
def __init__(self, parent = None):
    QDialog.__init__(self,  parent)
    self.setupUi(self)

@pyqtSignature("")
def on_btn_get_ref_dir_released(self):
    print '2nd form'

class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self, parent = None):
    """
    Constructor
    """
    QMainWindow.__init__(self, parent)
    self.setupUi(self)

    self.prefs = QDialog()
    ui = Ui_prefs()
    ui.setupUi(self.prefs)

@pyqtSignature("")
def on_btn_process_released(self):
    print 'process'
    no_of_shots = self.spn_no_of_shots.value()

    #spot_path = self.le_proj_path.text()+'\\'+self.lst_spots.selectedItems()[0].text()
    spot_path_string = 'self.le_proj_path.text())+os.sep,'
    spot_path_string += str(self.lst_spots.selectedItems()[0].text())    
    os.path.join(spot_path_string)                                                                      

    save_position = self.lst_spots.selectedItems()[0]

    if no_of_shots > 0:
        if self.cmb_mode.currentText() == 'Create Shots':
            print ('creating shots')
            for x in range(1, no_of_shots+1):
                make_render_folders.create_shot_folder(spot_path,  x)
        else:   
            print ('inserting shots')
            if self.lst_shots.count() > 0:
                t =self.lst_shots.selectedItems()[0].text()
                cur_shot = t[2:]
                cur_shot_val = int(cur_shot)
                cur_index = self.lst_shots.currentRow()
                print('sel_value :'+cur_shot)
                print('sel_index :'+str(cur_index))

                next_shot_index = int(cur_index)+1
                print('nextshot_index ='+str(next_shot_index))
                next_shot_text = self.lst_shots.item(next_shot_index).text()
                next_shot_val = int(next_shot_text[2:])
                print('nextshot value ='+str(next_shot_val))

                insert_space = next_shot_val - cur_shot_val
                print(str(insert_space))

                if no_of_shots > (insert_space-1) :
                    print "not enough space - please reduce shots to insert"
                else:
                    print('insert the shots')
                    for x in range(cur_shot_val,(cur_shot_val+no_of_shots) ):
                        print (str(x))
                        make_render_folders.insert_shot_folder(spot_path,  x+1)

    make_render_folders.populate_shot_list(self)
    self.lst_shots.setCurrentRow(0)

@pyqtSignature("")
def on_btn_quit_released(self):
    print 'quit'
    self.close()

@pyqtSignature("")
def on_cmb_mode_currentIndexChanged(self,  ret_text):
    print ret_text

@pyqtSignature("")   
def on_le_proj_path_editingFinished(self):
    print "editingFinished le_proj_path"

def on_le_new_spot_name_textChanged(self):
    if len(self.le_new_spot_name.text()) > 0 :
        self.btn_add_spot.setEnabled(True)
    else :
        self.btn_add_spot.setEnabled(False)

@pyqtSignature("")
def on_btn_add_spot_released(self):
    v_NewSpotFolder = self.le_new_spot_name.text()
    v_rPath =  self.le_proj_path.text()
    x = make_render_folders.create_spot_folder(v_NewSpotFolder,v_rPath)
    if x :
        self.le_new_spot_name.clear()    
        make_render_folders.populate_spots_list(self)

@pyqtSignature("")
def on_actionLoad_Project_triggered(self):
    print "actionLoad_Project"

    self.lst_shots.clear()
    self.lst_spots.clear()

    proj_dir = str(QFileDialog.getExistingDirectory(self, 'Select Project'))
    print proj_dir

    if os.path.exists(proj_dir):
        print 'the file is there'
    elif os.access(os.path.dirname(proj_dir), os.W_OK):
        print 'the file does not exists but write privileges are given'
    else:
        print 'can not write there'

    p = os.path.join(proj_dir+os.sep,'renders')

    self.le_proj_path.setText(p)

    make_render_folders.populate_spots_list(self)

@pyqtSignature("")    
def on_actionConfig_triggered(self):
    print "config"
    self.prefs.show()

@pyqtSignature("")
def on_actionQuit_triggered(self):
    print "ActionQuit"

@pyqtSignature("")
def on_btn_get_folders_released(self):
    make_render_folders.populate_spots_list(self)

def on_lst_spots_itemClicked (self):
    print "got you"

    self.lst_shots.clear()
    make_render_folders.populate_shot_list(self)

谢谢!!!

【问题讨论】:

【参考方案1】:

Prefs 窗口的事件处理可以在任何地方进行。就我个人而言,我总是更喜欢为每个窗口提供自己的文件。

所以 py 文件看起来像这样:

Mainwindow.py(主窗体事件等) Ui_make_render_folders.py(Qt 设计器生成的 UI) prefs.py(Prefs 表单事件等) ui_prefs.py(Qt Designer 生成的 UI) 您的其他文件...

初始化: (MainWindow.py)

from PyQt4.QtGui import QMainWindow
from Ui_make_render_folders import Ui_MainWindow

#prefs here refers to the file: prefs.py. PrefWindow is the class within this file.
from prefs import PrefWindow

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        #Better way to initialise
        super(MainWindow, self).__init__(parent)
        self.main = Ui_MainWindow()
        self.main.setupUi(self)

        #initialise prefs to variable
        self.prefs = PrefWindow(self)

        # Rest of init...

注意:第二种形式的初始化将与上述类似。 您应该将 prefs 表单的所有事件放在其类中。

来自调用 Prefs 的函数:

@pyqtSlot()
def on_actionConfig_triggered(self):
    print "config"
    self.prefs.exec_()  # Will block main window while its open.
    # Use self.prefs.show() if you want user to be able to interact with main window

最后: pyqtSignature

在http://pyqt.sourceforge.net/Docs/PyQt4/old_style_signals_slots.html 上声明:

'QtCore.pyqtSignature() 与 pyqtSlot() 装饰器的用途相同,但具有较少的 Pythonic API。'

最好使用pyqtSlot()

【讨论】:

以上是关于使用 PyQT 从第二个表单中捕获按钮方法的主要内容,如果未能解决你的问题,请参考以下文章

如何打开一个新表单然后从第二个表单返回到第一个表单而不关闭并重新打开第一个表单

通过一次提交发送双表单,同时将电子邮件字段从第一个表单拉到第二个表单

从第二个线程引发事件到主线程,没有表单[重复]

从第二个屏幕导航回来并刷新页面颤动时关闭 AlertDialog

PyQt5 - 第二个窗口中的按钮在单击时不执行操作

Xamarin 表单从另一个视图获取数据