วิธีเรียกใช้ฟังก์ชันใน pyside MainWindow จากสคริปต์ python อื่น

นี่คือ 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

นี่คือไฟล์หลามอื่นของฉันซึ่งเป็นตัวฟังหลักและฉันต้องการฟังก์ชัน 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()

person Peter Collazo    schedule 28.04.2015    source แหล่งที่มา
comment
ไม่ชัดเจน 100% ว่าคุณถามอะไร แต่ดูเหมือนว่าคุณต้องการเรียกเมธอดที่ถูกผูกไว้ (เมธอดที่มี self เป็นพารามิเตอร์แรกในกรณีของคุณ loadShot) โดยไม่ต้องสร้างอินสแตนซ์ของคลาสของคุณ คุณไม่สามารถทำอย่างนั้นได้ คุณสามารถทำให้วิธีการนั้นเป็นวิธีการเรียนได้ แต่แล้วคุณจะสูญเสียการอ้างอิงไปยังตัวแปรอินสแตนซ์เช่น self.shotName_Line.text() เป็นต้น คุณสามารถขยายสิ่งที่คุณพยายามทำให้สำเร็จเพียงเล็กน้อยได้หรือไม่?   -  person all or None    schedule 29.04.2015
comment
ขอบคุณที่ตอบกลับ ฉันมี main.py ซึ่งมี pyside gui MainWindow ของฉัน ฉันมีวิธีการบางอย่างที่โต้ตอบกับกุย loadShot() รับข้อมูลจากการแก้ไขบรรทัดและเขียนลงในไฟล์ ในไฟล์ other.py ของฉัน ฉันมีตัวฟังคีย์บอร์ดซึ่งมีเมธอด handle_CTRL_L () ฉันต้องการที่จะเรียกเมธอด loadShot() ได้ นี่ไม่สามารถเป็นอินสแตนซ์ได้เพราะมันจะเปิด GUI ของฉันอีกครั้ง ฆ่าข้อมูลทั้งหมดและไม่เขียนอะไรเลยลงในไฟล์ ฉันหวังว่าจะสามารถใช้สัญญาณที่กำหนดเองภายใต้เมธอด handle_ctrl_L() ที่ปล่อยออกมาเมื่อมีการเรียกใช้เมธอด ขอบคุณ.   -  person Peter Collazo    schedule 29.04.2015


คำตอบ (2)


ในโปรเจ็กต์หนึ่งฉันต้องเปิดใช้งานหนึ่งโมดูลเพื่อโทรกลับไปยังโมดูล Mainwindow ของฉัน ตัวควบคุมของมุมมอง Mainwindow เริ่มกระบวนการย่อยใหม่และดึง stdout ออกรวมทั้งการโทรกลับทันทีที่โปรแกรมถูกยกเลิก ฉันจัดการสิ่งนี้ด้วยวิธีต่อไปนี้: (อาจช่วยแก้ปัญหาของคุณได้ ซึ่งฉันไม่เข้าใจทั้งหมด)

โมดูลหน้าต่างหลัก:

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) 
person Ben    schedule 30.04.2015

หากแอปพลิเคชันของคุณต้องการ 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() มันก็จะส่งคืนอินสแตนซ์เดิมเสมอ

person ekhumoro    schedule 30.04.2015
comment
PS: ทำไมคุณถึงใช้ Tkinter file-dialog? เกิดอะไรขึ้นกับ QFileDialog? - person ekhumoro; 30.04.2015
comment
ใช่ฉันรู้ว่ามันเป็นโค้ดเก่าจากการทดสอบ ฉันได้เปลี่ยนมันออกจาก QFILEDIALOG แล้ว ขอบคุณ - person Peter Collazo; 05.05.2015