2

これは私がかなりの量のドキュメントを見たものですが、私の知識のこの特定のギャップに対する正確な答えを得ることができず、それのために壁にぶつかり続けています。このレベルでは実際には何もカバーしていないようです。

いくつかのウィンドウがあり、それらはすべてドラッグ可能である必要があるため、ユーティリティファイルを作成しています。このファイルにはこれがあります:

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

そして、これは、実際のウィンドウで1つのファイルに入れて(別のファイルから呼び出さないで)機能します。

問題は、別のファイル(UIウィンドウがあるファイル)からこれを呼び出すにはどうすればよいですか?

私はそれを呼んでいます

 from utils import *

したがって、技術的には、これらの関数はすべて、入力するだけでアクセスできます

mouseReleaseEvent(x,x)

しかし、これらの関数をインポートするにはUIが必要なので、「from utils import *」を配置した後のメインファイルに、次のように入力します。

self.moving = False

しかし、そのエラーは私が何をしても。それで、問題は、UIファイル内からそれらを呼び出すことができるように、最初にリストされた関数(最初のコードブロック)を囲む適切な方法は何ですか?

これが私の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_())

長い間AutodeskMaya内からのみPythonを学習して使用したため、Pythonの知識に大きなギャップがあります。現在、このギャップを埋めようとしています。助けてくれてありがとう。

4

2 に答える 2

4

あなたが探しているのはミックスインだと思います:

たとえば、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

関連するメソッドをミックスインにまとめると、基本クラスにミックスインを追加するだけで、クラス (ウィンドウ) に機能を追加できます。

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_())

上記のコードで気に入らない点の 1 つは、によって自動的に呼び出されるを使用して mixin (たとえばDraggable)を定義する方法を理解できなかったことです。通常はこれを使用しますが、それ自体は を呼び出していないようです。__init__viBadOSUI.__init__superQtGui.QDialog.__init__super

(実際には、ミックスインを の前に置くと使用できるsuper 思いますが、これは、ベースのリストの最後に表示する必要があることを誰かが忘れると壊れるトリックに依存しています。) QtGui.QDialogQtGui.QDialog

__init__堅牢に機能するメソッドを定義できなかったため、次のようにします。

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

代わりにmouseMoveEvent、を使用するように変更しましたtry..except。この属性は Draggable でのみ使用されるため、にself.moving = False直接追加するよりも優れているため、何らかの形で にバンドルする必要があります。ミックスインを設定してから、ミックスインが機能するように属性を初期化すること覚えておく必要があるのは、見苦しいプログラミングです。viBadOSUI.__init__Draggable

例外が発生しない限り試行が高速であり、最初の mousePressEvent の前の最初にのみ例外が発生するため、ここで使用try..exceptする方がおそらく使用するよりもわずかに優れています。if hasattr(self, 'moving')

それでも、改善の余地はあります。ここにいる誰かがより良い方法を示してくれることを願っています。

別のアプローチは、定義することでした

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長期的には、コードをより整理しておくことができます。

于 2012-06-13T18:17:50.753 に答える
2

メソッドのself(最初の) 引数は、それがバインドされているインスタンスを参照します。メソッドの外側に相当するのは、インスタンスの属性self.moving = FalseにバインドFalseすることです。movingobj.moving = False

于 2012-06-13T18:10:18.980 に答える