【问题标题】:How to call a function in pyside MainWindow from another python script如何从另一个python脚本调用pyside MainWindow中的函数
【发布时间】:2015-04-28 16:19:54
【问题描述】:

这是我的 main.py 我有一个名为 loadShot 的函数,我想从另一个函数调用它

class MainWindow(QMainWindow):
    # Main Window UI
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        loadUi(os.path.join(SCRIPT_DIRECTORY, 'mainwindow.ui'), self)

        self.connectInterface()

    # Connect signals
    def connectInterface(self):
        self.scene_Line.textChanged.connect(self.shotName)
        self.activeProjcet_Line.textChanged.connect(self.shotName)
        self.character_Line.textChanged.connect(self.shotName)
        self.take_Line.valueChanged.connect(self.shotName)
        self.load_Button.setShortcut(QKeySequence("Alt+B"))

    ####################################################
    #   Shot Loader Functions
    ####################################################


    def browse(self, dir):
        root = Tkinter.Tk()
        root.withdraw() #use to hide tkinter window

        tempdir = tkFileDialog.askdirectory(parent=root, initialdir=dir, title='Please select a directory')

        if tempdir.startswith('D:/Capture data/'):
            self.activeProjcet_Line.setText(tempdir)
        elif tempdir.startswith('R:/Project Files/'):
            self.uploadProjcet_Line.setText(tempdir)
            self.uploadFolder()
        else:
            pass

    def uploadFolder(self):
        project = self.activeProjcet_Line.text()
        uploadDir = self.uploadProjcet_Line.text()
        f = open('C:/_Mocap/output/folderName.txt', 'w')
        f.write(' \n' + project.replace('D:/Capture data/', '') + '\n' + uploadDir.replace('R:/Project Files/', ''))
        f.close()

    def loadShot(self):
        shot = self.shotName_Line.text()
        f = open('C:/_Mocap/output/ShotLoader.txt', 'w')
        f.write('\n' + '[name]\n' + '\n' + 'take Name=' + shot)
        f.close()
        self.uploadFolder()
        if self.incrementTake.isChecked():
            self.takeIncrement()
        else:
            pass

这是我的另一个 python 文件,它是一个关键的侦听器,我想要 loadShot 函数。问题是我一直将 MainWindow 作为实例加载。这是我做不到的。我只需要能够在我的 MainWindow 类中调用该函数而无需加载另一个实例。

def handle_Ctrl_L ():
    m = MainWindow()
    m.loadShot()
    hk = HotKeys()
    w = WindowMgr()
    pid = w.GetProcessID('Blade')
    w.focusWindow(pid)
    time.sleep(.2)
    hk.F8()

【问题讨论】:

  • 这不是 100% 清楚你在问什么,但听起来你想调用一个绑定方法(一个以 self 作为第一个参数的方法,在你的情况下是 loadShot)实例化你的类。你不能那样做。您可以将该方法设为类方法,但随后您将失去对实例变量的引用,例如 self.shotName_Line.text() 等。您能否扩展一下您实际想要实现的目标?
  • 感谢您的回复。我有我的 main.py,其中有我的 pyside gui MainWindow。我有一些与 gui 交互的方法。 loadShot() 从行编辑中获取信息并将其写入文件。在我的 other.py 文件中。我有一个键盘监听器,它有方法 handle_CTRL_L () 我希望能够调用 loadShot() 方法。这不能是一个实例,因为它重新启动了我的 gui。杀死所有信息并且不向文件写入任何内容。我希望能够在调用该方法时发出的 handle_ctrl_L() 方法下使用自定义信号。谢谢。

标签: python qt pyqt pyside mainwindow


【解决方案1】:

在一个项目中,我必须启用一个模块来回调我的主窗口模块。主窗口视图的控制器启动一个新的子进程,并在程序终止后立即检索标准输出以及回调。我通过以下方式进行管理:(也许它有助于解决您的问题,我不完全理解)

主窗口模块:

def run_program():
    # consoleprocess is the second module that 
    # has to be able to do a callback. 
    # A new Instance of the ProcessRunner class is created.

    self.progrunner = consoleprocess.ConsoleProcessRunner()
    self.progrunner.cout.connect(self.cb_update_prog_output)
    self.progrunner.quit.connect(self.cb_prog_terminated)

@QtCore.Slot(int)
@QtCore.Slot(str)
def cb_update_tv(self, data):
    # your code goes here
    pass

第二个模块(控制台进程):

# The Class has to inherit QtCore.Object

class ConsoleProcessRunner(QtCore.QObject):
    # The Signals that allow the callback are declared

    cout = QtCore.Signal(str)
    quit = QtCore.Signal(int)

    # Constructor
    def __init__(self, parent = None):
        super(ConsoleProcessRunner, self).__init__(parent)


    def your_function_here():
        # now you can use our previously defined signals to do the callback
        # your code goes here
        self.cout.emit(stdoutdata)
        self.quit.emit(ret) 

【讨论】:

    【解决方案2】:

    如果您的应用程序只需要一个 MainWindow 实例,那么您可以通过将其设为单例类来实现您想要的:

    class MainWindow(QMainWindow):
        _instance = None
        _initialized = False
    
        def __new__(cls):
            if cls._instance is None:
                cls._instance = super(MainWindow, cls).__new__(cls)
            return cls._instance
    
        def __init__(self, parent=None):
            if not self._initialized:
                super(MainWindow, self).__init__(parent)
                loadUi(os.path.join(SCRIPT_DIRECTORY, 'mainwindow.ui'), self)
                self.connectInterface()     
                self._initialized = True        
    

    现在每当调用MainWindow() 时,它总是会返回相同的实例。

    【讨论】:

    • PS:你为什么要使用Tkinter文件对话框? QFileDialog 怎么了?
    • 是的,我知道这是来自测试的旧代码。我已经为 QFILEDIALOG 切换了它。谢谢
    猜你喜欢
    • 1970-01-01
    • 2022-08-19
    • 1970-01-01
    • 1970-01-01
    • 2018-10-24
    • 1970-01-01
    • 2017-11-09
    • 1970-01-01
    • 2013-03-13
    相关资源
    最近更新 更多