2016-03-18 5 views
0

Я использую Qt Designer для разработки своих пользовательских интерфейсов, и я хочу, чтобы создавать собственные виджеты, которые могут быть комбинацией существующих виджетов Qt, такими как QLabel и QPushButton прилагается скриншотQt Designer способствовал виджету раскладки

enter image description here.

Теперь я хотел бы, чтобы это было независимым с его собственной бизнес-логикой, сигналами и слотами в отдельном файле python, но хотелось бы добавить это как компонент на главный экран.

Я попытался сделать это, создав отдельный файл типа виджета, но когда я продвигаю это из моего MainWindow, он не будет отображаться, а код, созданный pyuic, добавит его в макет, но он не отображается в главном окне.

enter image description here

Есть ли способ сделать это в PyQt и QDesigner?

EDIT:

Вот фактический код:

timer.py:

from PyQt4 import QtGui, QtCore 
from datetime import timedelta, datetime 

from logbook import info 


import timer_ui 


class Timer(QtGui.QWidget, timer_ui.Ui_TimerWidget): 

    start_time = None 
    running = False 
    total_time = 0 
    time_spent = '' 

    activity = None 

    stopwatch = 0 
    elapsed_time = None 
    total_elapsed_time = timedelta() 

    def __init__(self, parent=None): 
     super(self.__class__, self).__init__(parent) 

     self.setupUi(parent) #for custom widget parent is main window here which is dashboard 

     self.lcdNumber.setDigitCount(12) 

     self.qt_timer = QtCore.QTimer(self) 
     self.qt_timer.timeout.connect(self.timer_event) 
     self.qt_timer.start(1000) 

     self.goButton.clicked.connect(self.go) 
     self.breakButton.clicked.connect(self.break_timer) 

    def go(self): 
     # date text format .strftime('%a, %d %b %Y %H:%M:%S') 
     self.start_time = datetime.now().replace(microsecond=0) 
     self.running = True 




     self.goButton.setEnabled(False) 
     self.breakButton.setEnabled(True) 

    def break_timer(self): 
     ''' break finishes the activity ''' 
     break_time = datetime.now().replace(microsecond=0) 
     self.activity.log_break(break_time.isoformat()) 
     self.activity = None # activity completed 

     self.total_elapsed_time += self.elapsed_time 
     info(self.total_elapsed_time) 

     self.running = False 


     # self.lcdNumber.display(str(self.timer.get_elapsed())) 

     self.goButton.setEnabled(True) 
     self.breakButton.setEnabled(False) 


    def timer_event(self): 
     '''Updates the widget every second''' 

     if self.running == True: 
      current_time = datetime.now().replace(microsecond=0) 

      # if self.elapsed_time is None: 

      self.elapsed_time = current_time - self.start_time 
      # else: 
      #self.elapsed_time += current_time - self.timer.start_time.replace(microsecond=0) 
      if self.total_elapsed_time is not None: 
       self.lcdNumber.display(str(self.elapsed_time + self.total_elapsed_time)) 
      else: 
       self.lcdNumber.display(str(self.elapsed_time)) 

mainwindow.py:

# -*- coding: utf-8 -*- 

# Form implementation generated from reading ui file 'dashboard.ui' 
# 
# Created: Sat Mar 19 11:40:35 2016 
#  by: PyQt4 UI code generator 4.10.4 
# 
# WARNING! All changes made in this file will be lost! 

from PyQt4 import QtCore, QtGui 

try: 
    _fromUtf8 = QtCore.QString.fromUtf8 
except AttributeError: 
    def _fromUtf8(s): 
     return s 

try: 
    _encoding = QtGui.QApplication.UnicodeUTF8 
    def _translate(context, text, disambig): 
     return QtGui.QApplication.translate(context, text, disambig, _encoding) 
except AttributeError: 
    def _translate(context, text, disambig): 
     return QtGui.QApplication.translate(context, text, disambig) 

class Ui_MainWindow(object): 
    def setupUi(self, MainWindow): 
     MainWindow.setObjectName(_fromUtf8("MainWindow")) 
     MainWindow.resize(772, 421) 
     self.centralwidget = QtGui.QWidget(MainWindow) 
     self.centralwidget.setObjectName(_fromUtf8("centralwidget")) 
     self.verticalLayout = QtGui.QVBoxLayout() 
     self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) 
     self.widget = Timer(self.centralwidget) 

     self.verticalLayout.addWidget(self.widget) 

     self.horizontalLayout = QtGui.QHBoxLayout() 

     self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) 
     self.userNameLabel = QtGui.QLabel(self.centralwidget) 
     self.userNameLabel.setObjectName(_fromUtf8("userNameLabel")) 
     self.horizontalLayout.addWidget(self.userNameLabel) 
     self.logoutButton = QtGui.QPushButton(self.centralwidget) 
     self.logoutButton.setEnabled(True) 
     self.logoutButton.setObjectName(_fromUtf8("logoutButton")) 
     self.horizontalLayout.addWidget(self.logoutButton) 

     self.verticalLayout.addLayout(self.horizontalLayout) 

     self.listView = QtGui.QListView(self.centralwidget) 
     self.listView.setObjectName(_fromUtf8("listView")) 
     self.verticalLayout.addWidget(self.listView) 
     MainWindow.setCentralWidget(self.centralwidget) 
     self.statusbar = QtGui.QStatusBar(MainWindow) 
     self.statusbar.setObjectName(_fromUtf8("statusbar")) 
     MainWindow.setStatusBar(self.statusbar) 
     self.menuBar = QtGui.QMenuBar(MainWindow) 
     self.menuBar.setGeometry(QtCore.QRect(0, 0, 772, 23)) 
     self.menuBar.setObjectName(_fromUtf8("menuBar")) 
     MainWindow.setMenuBar(self.menuBar) 

     self.retranslateUi(MainWindow) 
     QtCore.QMetaObject.connectSlotsByName(MainWindow) 

    def retranslateUi(self, MainWindow): 
     MainWindow.setWindowTitle(_translate("MainWindow", "Title", None)) 
     self.userNameLabel.setText(_translate("MainWindow", "You are now logged in as", None)) 
     self.logoutButton.setText(_translate("MainWindow", "Logout", None)) 

from timer import Timer 

timer_ui.py:

# -*- coding: utf-8 -*- 

# Form implementation generated from reading ui file 'timer.ui' 
# 
# Created: Sat Mar 19 11:41:40 2016 
#  by: PyQt4 UI code generator 4.10.4 
# 
# WARNING! All changes made in this file will be lost! 

from PyQt4 import QtCore, QtGui 

try: 
    _fromUtf8 = QtCore.QString.fromUtf8 
except AttributeError: 
    def _fromUtf8(s): 
     return s 

try: 
    _encoding = QtGui.QApplication.UnicodeUTF8 
    def _translate(context, text, disambig): 
     return QtGui.QApplication.translate(context, text, disambig, _encoding) 
except AttributeError: 
    def _translate(context, text, disambig): 
     return QtGui.QApplication.translate(context, text, disambig) 

class Ui_TimerWidget(object): 
    def setupUi(self, TimerWidget): 
     TimerWidget.setObjectName(_fromUtf8("TimerWidget")) 
     TimerWidget.resize(412, 52) 
     self.horizontalLayout = QtGui.QHBoxLayout(TimerWidget) 
     self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) 
     self.label = QtGui.QLabel(TimerWidget) 
     self.label.setObjectName(_fromUtf8("label")) 
     self.horizontalLayout.addWidget(self.label) 
     self.lcdNumber = QtGui.QLCDNumber(TimerWidget) 
     self.lcdNumber.setAutoFillBackground(False) 
     self.lcdNumber.setNumDigits(12) 
     self.lcdNumber.setSegmentStyle(QtGui.QLCDNumber.Flat) 
     self.lcdNumber.setObjectName(_fromUtf8("lcdNumber")) 
     self.horizontalLayout.addWidget(self.lcdNumber) 
     self.goButton = QtGui.QPushButton(TimerWidget) 
     self.goButton.setObjectName(_fromUtf8("goButton")) 
     self.horizontalLayout.addWidget(self.goButton) 
     self.breakButton = QtGui.QPushButton(TimerWidget) 
     self.breakButton.setObjectName(_fromUtf8("breakButton")) 
     self.horizontalLayout.addWidget(self.breakButton) 

     self.retranslateUi(TimerWidget) 
     #QtCore.QMetaObject.connectSlotsByName(TimerWidget) 

    def retranslateUi(self, TimerWidget): 
     #TimerWidget.setWindowTitle(_translate("TimerWidget", "Form", None)) 
     self.label.setText(_translate("TimerWidget", "Total hours spent", None)) 
     self.goButton.setText(_translate("TimerWidget", "Go!", None)) 
     self.breakButton.setText(_translate("TimerWidget", "Break", None)) 

ответ

1

продвигаемых виджеты только заполнители для стандартных виджетов Qt. Вы не можете создать собственный виджет для Qt Designer таким образом.

Это можно сделать, но процесс намного сложнее, чем просто продвижение виджета. См. Writing Qt Designer Plugins в документах PyQt и подробный учебник, см. Using Python Custom Widgets In Qt Designer в вики Python. В PyQt source code также есть много других примеров (смотрите в примеры/дизайнер/плагины).

EDIT:

Есть две проблемы с вашим кодом. Во-первых, вы передаете неправильный аргумент в setupUi в классе Timer. Вы должны исправить это следующим образом:

class Timer(QtGui.QWidget, timer_ui.Ui_TimerWidget): 
    ... 
    def __init__(self, parent=None): 
     super(Timer, self).__init__(parent) 
     self.setupUi(self) # pass in self, not parent 

Во-вторых, вы редактировали файл mainwindow.py и сломал одну из раскладок. Никогда, Редактировать модули, созданные pyuic! Линия вы сломали это один:

 # self.verticalLayout = QtGui.QVBoxLayout() 
     self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget) 

Но не пытайтесь исправить это, отредактировав - вместо этого, убедитесь, что вы регенерировать все Ui модули с pyuic так что вы получите обратно чистить, неотредактированные файлы снова ,

+0

Я не хочу отображать его в qt-дизайнере, но только продвигаю его, который я могу сейчас. Но мой пользовательский виджет, который представляет собой составной элемент стандартного виджета, должен отображаться, когда мое приложение скомпилировано в том же месте, что и мой заполнитель. –

+0

@AftabNaveed. Ну, тогда вам нужно опубликовать какой-то фактический код. Изображения от Qt Designer вообще не нужны для отладки. – ekhumoro

+0

timer_ui generated by QtDesigner http://pastebin.com/XeDaFjk8 моя обертка вокруг этого ui здесь http://pastebin.com/GwwLTpP9 и, наконец, MainWindow здесь http://pastebin.com/fDK9yiLd MainWindow является родительским заполнителя, а владелец места - timer.py, который обертывается вокруг виджета, созданного QtDesigner. Это прекрасно работает, но я не могу правильно его выровнять. –

0

Я делаю это все время, то есть создаю пользовательские виджеты и использую их в своем главном окне.

Я не знаю, что это верхний виджет уровня для пользовательского виджета, но предпочтительно должно быть QWidget или QFrame из списка Containers в конструкторе Qt и добавить дочерние виджеты внутри него, давайте назовем этот собственный виджет файл как custom.ui.

Далее создайте класс Python следующим образом:

Form, Base = uic.loadUiType('/path/to/custom.ui') # this path should be a relative path. For testing you can use absolute path. 
class CustomWidget(Form, Base): 
    def __init__(self, parent=None): 
     super(CustomWidget, self).__init__(parent) 
     self.setupUi(self) 

Вы можете добавить любое количество сигналов и слотов для пользовательской логики в класс выше.

Аналогичным образом создайте класс для вашего основного окна, а затем создайте объект из CustomWidget внутри этого основного класса и добавьте этот объект в макет.

Form2, Base2 = uic.loadUiType('/path/to/dashboard.ui') # this path should be a relative path. For testing you can use absolute path. 
class Window(Form2, Base2): 
    def __init__(self, parent=None): 
     super(Window, self).__init__(parent) 
     self.setupUi(self) 
     self.cWidget = CustomWidget(self) 
     self.layout.addWidget(self.cWidget) 

Примечание: Этот код совместим с Python 2.x, если вы используете Python 3.x, внести необходимые изменения. Этот код не проверен, поэтому ошибки синтаксиса также должны быть устранены, если они найдены.

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