简体   繁体   English

Qt Designer提升了小部件布局

[英]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 ”列表中的QWidgetQFrame并在其中添加子窗口小部件,让我们将此自定义窗口小部件文件命名为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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM