2011-12-17 36 views
5

Trong các khoảng thời gian đều đặn của chương trình của tôi, cần phải thêm một khối (trong số 3 ô xếp chồng) vào bố cục nằm ngang. Kể từ khi các vật dụng trong mỗi khối là quan trọng đối với eachother, tôi muốn đóng gói mỗi ngăn xếp như là widget riêng của nó (làm cho việc bố trí thêm kinh doanh dễ dàng hơn nhiều).PyQt4 - Cấu trúc lớp tiện ích tùy chỉnh?

Tôi gặp sự cố khi PyQt4 nhận ra 'chồng' của tôi làm tiện ích.

Tôi đã tạo ngăn xếp tiện ích trong Nhà thiết kế Qt (dưới dạng biểu mẫu: tiện ích con) và chuyển đổi nó thành .py qua
'pyuic4 DesignerFile.ui> ClassFile.py'.

Bây giờ tôi không thể thêm 'ngăn xếp' này (tiện ích con của 3 tiện ích con) vào bố cục qua .addWidget (Lớp).

tôi đã cố gắng xây dựng một lớp siêu của lớp ngăn xếp (vì tôi cần thêm nhiều chức năng hơn để ngăn xếp) nhưng trường hợp của lớp được một trong hai ...

  • Không công nhận là một widget
  • Ẩn số
  • bị lỗi vì tôi không có ý tưởng về cách cấu trúc lớp siêu.

Dưới đây là những gì tôi đang thất bại với tại thời điểm này (mặc dù đó là về cấu trúc lớp 8 tôi đã cố gắng):

from ClassFile import ClassCode 

class Stack(ClassCode): 
    def __init__(self,parent= None): 
     QtGui.QWidget.__init__(self,parent) 

ai đó có thể giúp tôi cấu trúc này hoặc đưa tôi đến với một số ví dụ tốt ?
(tôi đã bắt chước mã trong cả các nguồn sau đây nhưng không có avail !!
http://lateral.netmanagers.com.ar/stories/27.html#what-you-need-to-follow-the-tutorial
http://zetcode.com/tutorials/pyqt4/customwidgets/)

Cảm ơn!

Specs:
python 2.7.2
PyQt4
Windows 7

Trả lời

5

Khi bạn biên dịch một module python từ một tập tin ui với các tùy chọn mặc định, nó sẽ (trong số những thứ khác) tạo ra một "thiết lập" class đơn giản. Tóm lại, lớp thiết lập sẽ trông giống như sau:

class Ui_ClassCode(object): 
    def setupUi(self, ClassCode): 
     ClassCode.setObjectName("ClassCode") 
     # bunch of boiler-plate ui code goes here 
     self.retranslateUi(ClassCode) 
     QtCore.QMetaObject.connectSlotsByName(ClassCode) 

    def retranslateUi(self, ClassCode): 
     pass 

Có một vài vấn đề cần lưu ý ở đây có liên quan đến câu hỏi.

Thứ nhất, lớp thiết lập được thiết kế để được sử dụng như một mixin thay vì là một phân lớp trực tiếp.Nhiệm vụ của nó là "tiêm" ui vào một tiện ích lưu trữ được chuyển đến phương thức setupUI.

Thứ hai, lớp thiết lập được cung cấp một mã định danh xấu xí, không được tạo ra bằng cách thêm "Ui_" vào thuộc tính objectName được thiết lập trong Nhà thiết kế.

May mắn thay, pyuic4 cung cấp cách để bỏ qua hai vấn đề này. Tất cả những gì cần thiết là sử dụng tùy chọn -w khi biên soạn các mô-đun python từ tập tin ui:

pyuic4 -w designerfile.ui > classfile.py 

này sẽ bổ sung thêm một lớp wrapper rằng (1) có thể dễ dàng subclassed, và (2) có đẳng cấp tên mà bạn cũng đã cho nó trong thiết kế Qt.

Lớp wrapper sẽ giống như thế này:

class ClassCode(QtGui.QWidget, Ui_ClassCode): 
    def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()): 
     QtGui.QWidget.__init__(self, parent, f) 

     self.setupUi(self) 

Như bạn thấy, nó không làm bất cứ điều gì đặc biệt: bạn có thể dễ dàng sao chép những gì nó làm trong mã của riêng bạn. Nhưng, IMO, nó làm cho các mô-đun được biên dịch trực quan hơn nhiều để sử dụng.

Ví dụ:

from PyQt4 import QtGui, QtCore 
from classfile import ClassCode 

class Stack(ClassCode): 
    def __init__(self, parent=None): 
     ClassCode.__init__(self, parent) 

class Window(QtGui.QMainWindow): 
    def __init__(self): 
     QtGui.QMainWindow.__init__(self) 
     self.stack = Stack(self) 
     self.setCentralWidget(self.stack) 
+0

Có thể truyền một chuỗi cho hàm tạo (khi instantiation widget) được sử dụng thông qua widget không? Ví dụ: x = Stack ('cat') –

+1

@AntiEarth. Chắc chắn: bạn có thể thiết kế lớp con 'Stack' của mình theo bất kỳ cách nào bạn thích - giống như phân lớp bất kỳ tiện ích Qt nào khác. Vì vậy, chữ ký của 'Stack .__ init__' có thể được thay đổi thành ví dụ: '__init __ (self, name, parent = None)'. – ekhumoro

1

Đầu tiên, nó là thích hợp hơn để gọi phụ huynh __init__ với việc sử dụng super. Điều đó sẽ đảm bảo phương thức trong lớp siêu thích hợp được gọi. Thứ hai, khi sử dụng một lớp được xây dựng với pyuic, bạn cần gọi self.setupUi(self) từ phương thức __init__ của bạn. Và cuối cùng, bạn cần phải chắc chắn và thừa hưởng nhiều từ cả lớp Qt thích hợp và lớp được tạo ra pyuic (vốn thực sự là một mixin).

Vì vậy, một cái gì đó như thế này:

from ClassFile import ClassCode 

class Stack(QtGui.QWidget, ClassCode): 
    def __init__(self,parent= None): 
     super(Stack, self).__init__(parent) 
     self.setupUi(self) 
+1

Ông thực sự nên được thừa hưởng đầu tiên từ QWidget mong muốn, và thứ hai từ ClassCode đó được tạo ra bởi pyuic – jdi

+0

Cám ơn bắt đó. Tôi đã cập nhật câu trả lời của mình. –

Các vấn đề liên quan