[英]Qt Designer promoted widget layout
I am using Qt Designer for designing my user interfaces, and I want to build custom widgets which could be a combination of existing qt widgets such as a QLabel and QPushButton attached screenshot 我正在使用Qt Designer来设计用户界面,我想构建自定义窗口小部件,该窗口小部件可以是现有qt小部件的组合,例如QLabel和QPushButton附加的屏幕截图
Now I would like this to be independent with it's own business logic, signals and slots in a separate python file, but would want to add this as a component to my main screen. 现在,我希望这与它自己的业务逻辑,信号和插槽在一个单独的python文件中相互独立,但希望将此作为组件添加到我的主屏幕中。
I tried above by creating seprate ui file of type widget, but when I promote that from my MainWindow, it won't show up, and the code generated by pyuic would add it to the layout, but it is not rendered in main window. 我在上面通过创建类型为widget的单独的ui文件进行了尝试,但是当我从MainWindow升级该文件时,它不会显示,并且pyuic生成的代码会将其添加到布局中,但是不会在主窗口中呈现。
Is there a way of doing that in PyQt and QDesigner? 在PyQt和QDesigner中有没有办法做到这一点?
EDIT : 编辑 :
Here is the actual code: 这是实际的代码:
timer.py : 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 : 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 : 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))
Promoted widgets are just placeholders for standard Qt widgets. 促销小部件仅是标准Qt小部件的占位符。 You cannot create a custom widget for Qt Designer that way.
您不能以这种方式为Qt Designer创建自定义窗口小部件。
It can be done, but the process is much more complicated than simple widget promotion. 可以做到,但是过程比简单的小部件升级要复杂得多。 See Writing Qt Designer Plugins in the PyQt docs, and for a detailed tutorial, see Using Python Custom Widgets In Qt Designer on the Python Wiki.
请参阅PyQt文档中的编写Qt Designer插件 ,有关详细的教程,请参见Python Wiki上的在Qt Designer中使用Python自定义小部件 。 The PyQt source code also has many more examples (look in examples/designer/plugins ).
PyQt源代码还具有更多示例(请参阅 examples / designer / plugins )。
EDIT : 编辑 :
There are two problems with your code. 您的代码有两个问题。 Firstly, you are passing the wrong argument to
setupUi
in the Timer
class. 首先,您将错误的参数传递给
Timer
类中的setupUi
。 You should fix it like this: 您应该像这样修复它:
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
Secondly, you edited the mainwindow.py file and broke one of the layouts. 其次,您编辑了mainwindow.py文件并破坏了其中一种布局。 Never, ever edit the modules generated by
pyuic
! 永远不要编辑所产生的模块
pyuic
! The line you broke is this one: 您中断的行是这一行:
# self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)
But don't try to fix this by editing - instead, make sure you regenerate all the ui modules with pyuic
so you get back to clean, unedited files again. 但是不要尝试通过编辑来解决此问题-相反,请确保使用
pyuic
重新生成所有ui模块,以便再次返回到干净,未编辑的文件。
I do this all the time, ie build Custom widgets and use them inside my main window. 我一直都这样做,即构建“自定义”小部件并在主窗口中使用它们。
I don't know what is the top level widget for your custom widget, but it should preferably be QWidget
or QFrame
from the list of Containers
in the Qt Designer and add the child widgets inside it, let's name this custom widget file as custom.ui
. 我不知道什么是您的自定义窗口小部件的顶层窗口小部件,但最好是Qt Designer中“
Containers
”列表中的QWidget
或QFrame
并在其中添加子窗口小部件,让我们将此自定义窗口小部件文件命名为custom.ui
。
Next, create a Python class as follows: 接下来,创建一个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)
You can add any number of signals and slots for the custom logic to the above class. 您可以为自定义逻辑添加任意数量的信号和插槽到上述类中。
Similarly create a class for your main window and then create an object of CustomWidget
inside that main class and add that object to the layout. 同样,为您的主窗口创建一个类,然后在该主类内创建一个
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)
Note: This code is compatible with Python 2.x, if you are using Python 3.x, make necessary changes. 注意:此代码与Python 2.x兼容,如果您使用的是Python 3.x,请进行必要的更改。 This code is not tested, so syntax errors must also be resolved if found.
此代码未经测试,因此,如果发现语法错误,也必须解决。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.