一半君的总结纸

听话只听一半君

近年来依然中古的PyQt写UI的方法总结纸

Maya帮助自带一个用loadUI命令的方法,不过这方法和屎一样,不会有人用的,正确方法如下:

如果ui上没有太多动态元素的话,你可以用qt designer 画一个.ui文件出来,也可以直接在代码里写。对于不想当代码民工的人来说,用designer画就可以了,不过也许你画多了以后也就会写了

fuckme_designer

上图的.ui文件可以用

pyuic4 -o ui_pyqt_example.py pyqt_example.ui

来转换成.py文件,然后下面的用法稍有不同,下面的几个例子都是直接读取.ui文件,没有预先转换,因为我们Maya里平常用的UI都不是特别复杂,所以预先转换以换取读取速度的意义不大

The Single Inheritance Approach

方法1:

import os,sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyQt4 import uic

import maya.OpenMayaUI as apiUI
import sip

uiFile=os.path.join(os.path.dirname(__file__), 'pyqt_example.ui')

def getMayaWindow():
    ptr = apiUI.MQtUtil.mainWindow()
    return sip.wrapinstance(long(ptr), QObject)

class MyWindow(QDialog):
    def __init__(self,parent=getMayaWindow()):
        super(MyWindow,self).__init__(parent)
        self.ui = uic.loadUi(uiFile,self)
        self.ui.show()

def main():
    global win
    try:
        win.close()
    except:
        pass
    win = MyWindow()

if __name__ == "__main__":
	main()

方法1 在外部运行:

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyQt4 import uic

# enable ctrl-c to kill the app
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)

class MyWindow(QDialog):
	def __init__(self,parent=None):
		super(MyWindow,self).__init__(parent)

		self.ui = uic.loadUi('pyqt_example.ui',self)
		self.ui.show()

if __name__ == "__main__":
	app = QApplication(sys.argv)
	win = MyWindow()
	sys.exit(app.exec_())
  • 但是上面的方法访问ui上的widgets的时候得 self.ui.xxx,好像有点长.
  • 还有上面都是直接用 .ui文件的,如果你用pyuic4把.ui转成了py, 那也许你就可以用 self.ui.setupUi(self)了吧,我猜…
  • getMayaWindow()这个不是必要的,但是如果你的window的parent不是Maya的MainWindow的话,当Maya最小化的时候,你的窗口会浮在外面,不跟着Maya一起最小化

The Multiple Inheritance Approach

方法2:
(来自nathan网站)

import os
import sip

import maya.cmds as cmds
import maya.OpenMayaUI as mui

from PyQt4 import QtGui, QtCore, uic

def getMayaWindow():
	'Get the maya main window as a QMainWindow instance'
	ptr = mui.MQtUtil.mainWindow()
	return sip.wrapinstance(long(ptr), QtCore.QObject)

uiFile=os.path.join(os.path.dirname(__file__), 'pyqt_example.ui')

#Load the ui file, and create my class
form_class, base_class = uic.loadUiType(uiFile)
class MyWindow(base_class, form_class):
	def __init__(self, parent=getMayaWindow()):
		#init our ui using the MayaWindow as parent
		super(base_class, self).__init__(parent)
		#uic adds a function to our class called setupUi, calling this creates all the widgets from the .ui file
		self.setupUi(self)

def main():
    global win
    try:
        win.close()
    except:
        pass
    win = MyWindow()
    win.show()

if __name__ == "__main__":
	main()

方法2:在外部运行

import os,sys
from PyQt4 import QtGui, QtCore, uic
import sip

# enable ctrl-c to kill the app
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)

uiFile=os.path.join(os.path.dirname(__file__), 'pyqt_example.ui')

#Load the ui file, and create my class
form_class, base_class = uic.loadUiType(uiFile)
class MyWindow(base_class, form_class):
	def __init__(self, parent=None):
		#init our ui using the MayaWindow as parent
		super(base_class, self).__init__(parent)
		#uic adds a function to our class called setupUi, calling this creates all the widgets from the .ui file
		self.setupUi(self)

if __name__ == "__main__":
	app = QtGui.QApplication(sys.argv)
	win = MyWindow()
	win.show()
	sys.exit(app.exec_())
  • 上面的例子里,我有些地方用的是
    from PyQt4.QtGui import *
    from PyQt4.QtCore import *
    

    最好不要这样,还是应该

    from PyQt4 import QtGui, QtCore
    
  • ctrl-c关闭程序的那一段要不要都可以,但是有时候在console测试的时候比较方便

最终效果图:(左边是在Maya里运行,右边是在外面运行)

inMaya outsideMaya

参考:
Using Qt Designer
Using a Designer UI File in Your Application

拓展阅读:
使用Qt设计师文件的3种方式 by Jimmy Kuu
这虽然是在Maya外面使用,但是你在Maya里也一样,上面的方法相当于文中的方法1+3

edit:
lz觉得用 uic.loadUI() 比较好,不过如果文件拆成很多个单独的(widget class 放在单独的文件里了,也就无所谓了吧),或者没想着以后这个工具可以当成个python 的package, 方法2也行(我觉得想简单写写就方法2了,因为可以省去每次敲self.ui.xxx)

edit: 上述例子中检测现在是不是在maya里的try/except不好,应该用

QApplication.applicationName()
# Result: PyQt4.QtCore.QString(u'Maya-2012-x64') #

# 或者如果你已经from PyQt4.QtGui import *了, 你也可以用
qApp.applicationName()

pssss: 综上所述,最后全部合起来就是这样

import os
import sys
from PyQt4 import QtCore, QtGui
from PyQt4 import uic

uiFile = os.path.join(os.path.dirname(__file__), 'pyqt_example.ui')

try:
    import maya.OpenMayaUI as apiUI
    import sip

    def getMayaWindow():
        ptr = apiUI.MQtUtil.mainWindow()
        return sip.wrapinstance(long(ptr), QtCore.QObject)
except:
    pass


class MyWindow(QtGui.QDialog):

    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)
        self.ui = uic.loadUi(uiFile, self)
        self.ui.show()


def main():
    if QtGui.qApp.applicationName().startsWith('Maya'):
        global win
        try:
            win.close()
        except:
            pass
        win = MyWindow(getMayaWindow())
    else:
        app = QtGui.QApplication(sys.argv)
        win = MyWindow()
        sys.exit(app.exec_())

if __name__ == "__main__":
        main()

写代码的时候套用上面这个模板就行了

update:
此模板用于懒人提问

import os
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import uic


class MyWindow(QDialog):

    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)
        layout = QVBoxLayout()
        textedit = QTextEdit()
        button = QPushButton('test')
        layout.addWidget(textedit)
        layout.addWidget(button)
        self.setLayout(layout)


def main():
    if qApp.applicationName().startsWith('Maya'):
        global win
        try:
            win.close()
        except:
            pass
        win = MyWindow(getMayaWindow())
    else:
        app = QApplication(sys.argv)
        win = MyWindow()
        win.show()
        sys.exit(app.exec_())

if __name__ == "__main__":
    main()

Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

%d 博主赞过: