我正在使用Qt Designer来设计我的用户界面,我想构建自定义小部件,这些小部件可以是现有qt小部件的组合,例如QLabel和QPushButton附加的屏幕截图
现在我想在独立的python文件中独立使用它自己的业务逻辑,信号和插槽,但是希望将它作为组件添加到我的主屏幕。
我上面尝试创建了类型为widget的seprate ui文件,但是当我从我的MainWindow中提升它时,它将不会显示,而pyuic生成的代码会将它添加到布局中,但它不会呈现在主窗口。
在PyQt和QDesigner中有没有办法做到这一点?
修改:
以下是实际代码:
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))
答案 0 :(得分:1)
推荐的小部件只是标准Qt小部件的占位符。您无法以这种方式为Qt Designer创建自定义窗口小部件。
可以这样做,但这个过程要比简单的小部件推广复杂得多。请参阅PyQt文档中的Writing Qt Designer Plugins,有关详细教程,请参阅Python Wiki上的Using Python Custom Widgets In Qt Designer。 PyQt source code还有更多示例(请参阅 examples / designer / plugins )。
修改强>:
您的代码存在两个问题。首先,您将错误的参数传递给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)
但是不要试图通过编辑来解决这个问题 - 而是确保重新生成所有带有pyuic
的ui模块,这样你就可以再次回到干净的未经编辑的文件。
答案 1 :(得分:0)
我一直这样做,即构建自定义小部件并在我的主窗口中使用它们。
我不知道自定义窗口小部件的顶级窗口小部件是什么,但最好是Qt设计器中QWidget
列表中的QFrame
或Containers
并在其中添加子窗口小部件,让我们将此自定义窗口小部件文件命名为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,请进行必要的更改。此代码未经过测试,因此如果找到,也必须解决语法错误。