2012-06-13 3 views
2

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

У меня есть несколько окон, все они должны быть перетаскиваемы, поэтому я создаю файл утилиты. В этом файле у меня есть это:

def mouseMoveEvent(self, event): 
    if self.moving: self.move(event.globalPos()-self.offset) 

def mousePressEvent(self, event): 
    if event.button() == QtCore.Qt.LeftButton: 
     self.moving = True; self.offset = event.pos() 


def mouseReleaseEvent(self, event): 
    if event.button() == QtCore.Qt.LeftButton: 
     self.moving = False 

И это будет работать, если я ставлю его в один файл (и не требует от другого) с фактическим окном.

Вопрос в том, как я могу позвонить этому из другого файла (того, который имеет окно пользовательского интерфейса)?

Я звоню ему

from utils import * 

Технически эти функции являются доступными, просто набрав

mouseReleaseEvent(x,x) 

Но мне нужен интерфейс, чтобы импортировать эти функции, так что в основном файле после выставляя «из импорта utils *» Я печатаю:

self.moving = False 

Но это ошибки независимо от того, что Я делаю. Итак, вопрос в том, как правильно вложить функции, перечисленные первым (первый блок кода), чтобы я мог вызвать их из моего файла пользовательского интерфейса?

Вот мой код UI:

#!/usr/bin/env python 

    import sys 
    import os 
    from PyQt4 import QtCore, QtGui 
    from vibotCss import css 
    from viUtils import * 

    class viBadOSUI(QtGui.QDialog): 
     def __init__(self): 
      QtGui.QDialog.__init__(self) 
      #setup window 
      self.setWindowFlags(QtCore.Qt.FramelessWindowHint) 
      self.resize(300, 150) 
      center(self) 
      self.setMouseTracking(True) 



      #additional code 
      self.show() 
      self.setStyleSheet(css) 



    app = QtGui.QApplication(sys.argv) 
    window = viBadOSUI() 
    sys.exit(app.exec_()) 

У меня есть большие пробелы в моем знании Python из-за обучения и использовать его исключительно изнутри Autodesk Maya в течение длительного времени - я пытаюсь мостике зазоры в настоящее время. Спасибо за любую помощь.

ответ

2

Аргумент self (первый) для метода относится к экземпляру, на который он связан. Эквивалент self.moving = False вне метода заключается в связывании False с атрибутом moving экземпляра, например. obj.moving = False.

+0

Не быть грубым, но вы в значительной степени переформулировали мой вопрос, не предоставив ответа. Я с удовольствием прислушаюсь, если у вас есть решение :) – Vii

4

Я думаю, что вы ищете являются Mixins:

К примеру, в viUtils.py можно определить:

from PyQt4 import QtCore, QtGui 

class Draggable(object): 
    def mouseMoveEvent(self, event): 
     try: 
      if self.moving: 
       self.move(event.globalPos()-self.offset) 
     except AttributeError: 
      pass 

    def mousePressEvent(self, event): 
     if event.button() == QtCore.Qt.LeftButton: 
      self.moving = True; self.offset = event.pos() 

    def mouseReleaseEvent(self, event): 
     if event.button() == QtCore.Qt.LeftButton: 
      self.moving = False 

class Centerable(object): 
    pass # add code here 

class CountdownTimer(object): 
    pass # add code here 

Объединив связанные методы вместе в Mixins, вы можете добавить функциональность к классам (окна), просто добавив подмешать (ы) к базовым классам:

import sys 
import os 
from PyQt4 import QtCore, QtGui 
from vibotCss import css 
import viUtils 

class viBadOSUI(QtGui.QDialog, 
       viUtils.Draggable, viUtils.CountdownTimer): 

    def __init__(self):    
     QtGui.QDialog.__init__(self) 
     #setup window 
     self.setWindowFlags(QtCore.Qt.FramelessWindowHint) 
     self.resize(300, 150) 
     center(self) # You should probably make `center` a method instead of a function and call `self.center()` instead. 
     self.setMouseTracking(True) 

     #additional code 
     self.show() 
     self.setStyleSheet(css) 

app = QtGui.QApplication(sys.argv) 
window = viBadOSUI() 
sys.exit(app.exec_()) 

Одна вещь, которую я не люблю аЬ мой код выше - это то, что я не мог понять, как определить mixin (например, Draggable) с __init__, который автоматически вызывается автоматически по номеру viBadOSUI.__init__. Обычно для этого вы должны использовать super, но, похоже, QtGui.QDialog.__init__ сам не звонит super.

(На самом деле, я думаю, можно было бы использовать superесли вы положили Примеси перед темQtGui.QDialog, но это зависит от обмана, который сломается когда кто-то забывает, что QtGui.QDialog должен появиться последний в списке баз.)

Потому что я не мог определить __init__ метод, который будет работать робастно:

class Draggable(object): 
    def __init__(self): 
     ... 
     self.moving = False 

я вместо модифицированного mouseMoveEvent использовать try..except. Это лучше, чем добавление self.moving = False непосредственно к viBadOSUI.__init__, потому что этот атрибут используется только Draggable, и поэтому должен быть каким-то образом связан с Draggable. Установка mixin, а затем также, чтобы запомнить инициализацию атрибута, так что mixin будет работать уродливым программированием.

Использование здесь try..except здесь, возможно, немного лучше, чем использование if hasattr(self, 'moving'), поскольку попытка выполняется быстрее, пока исключение не возникает, и исключение будет поднято только в начале перед первым mousePressEvent.

Тем не менее, есть возможности для улучшения, и я надеюсь, что кто-то здесь покажет нам лучший способ.

Альтернативный подход был бы определить

class viBadOSUI(QtGui.QDialog): 
    mouseMoveEvent = viUtils.mouseMoveEvent 
    mousePressEvent = viUtils.mousePressEvent 
    mouseReleaseEvent = viUtils.mouseReleaseEvent 

Это дает большую гибкость, чтобы добавить именно те методы, которые вы хотите от viUtils непосредственно в любой класс, который вы определили. Тем не менее, я думаю, что это слишком большая гибкость, поскольку mouseMoveEvent, mousePressEvent и mouseReleaseEvent кажутся мне «связанными». Все они работают вместе, чтобы реализовать единую функциональность. Вот почему мне нравится подход mixin лучше. Кроме того, добавление viUtils.Draggable к базовым классам менее типично, чем добавление этих 3 строк к каждому подклассу окон, которые вы хотите перетаскивать.

Кстати, я бы рекомендовал отказаться от from viUtils import * и вместо этого использовать import viUtils. Он сохранит ваш код более организованным в долгосрочной перспективе.

+0

Эй, спасибо, что нашли время ответить. Я на самом деле все еще довольно потерян, но я сделал так, как вы сказали, и возникшая ошибка: RuntimeError: базовый объект C/C++ был удален - это происходит из-за строки viUtils.viDragUI .__ init __ (self) 'предположительно. – Vii

+0

Я проверил код, который я разместил. Я работаю (если вы закомментируете 'center (self)' и 'self.setStyleSheet (css)' - я предположил, что вы определили их в другом месте). Поэтому я не уверен, почему вы сталкиваетесь с «RuntimeError». Ошибка должна быть вызвана другим кодом, который не был отправлен! :) – unutbu

+0

Привет, проблема возникает из 'window = viBadOSUI()' говорит интерпретатор. Я прокомментировал ВСЕ, возможно, и все еще код не запускается, жалуясь на это. Есть еще одна вещь; Мне не нравится этот метод, и я не понимаю, почему я должен его использовать, потому что, если я хочу использовать несколько функций из моего файла viUtils.py, я не могу назвать их так, и это также кажется очень беспорядочно, действительно должен быть правильный способ сделать это [?] Не сказать, что я не ценю вашу помощь, но так, но это не так. – Vii

Смежные вопросы