I am having trouble getting a QWidget to real fullscreen in PyQt 4.8 . I took two approaches:
Code directly (this works)
import sys
from PyQt4 import QtGui, QtCore
import qimage2ndarray as q2n
import numpy as np
from scipy.misc.common import lena
class FullscreenWindow(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.qg = QtGui.QGraphicsView(self)
self.scene = QtGui.QGraphicsScene(self)
self.qg.setScene(self.scene)
# Make window fullscreen and always on top
self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
# set the image (lena)
qimg = q2n.array2qimage(np.pad(lena(), ((0,0),(0,0)), mode='constant'))
pix = QtGui.QPixmap(qimg)
self.scene.clear()
self.scene.addPixmap(pix)
self.show()
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.fullscreen = FullscreenWindow()
qdw = QtGui.QDesktopWidget()
screen = qdw.screenGeometry(screen=1)
self.fullscreen.setGeometry(screen)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
winMain = MainWindow(None)
winMain.show()
app.exec_()
Designed the window(s) with QtDesigner, having a QWidget with a QGraphicsView, set a QGraphicsScene with my Image. Basically the same code as above but importing the ui-file with the uic module. An image of the result is appended. I am always getting a gray border that appears to be part of the QWidget.
Why is that? How to get rid of it?
Problem is a bug with QGraphicsView::fitInView() they don't care about: https://bugreports.qt.io/browse/QTBUG-11945
Solution:
self.setViewportMargins(-2, -2, -2, -2)
self.setFrameStyle(QFrame.NoFrame)
self is QGraphicsView in this case, so you might want to change this.
To my knowledge, its the default style sheet of QWidgets adding that slight border to themselves; in this case QGraphicsView.
So, if set the style sheet on your main window through setStyleSheet, you can override the css to remove the border--
styleSheetCss="QGraphicsView {border-width: 0px;}"
self.setStyleSheet(styleSheetCss)
In your example-
class FullscreenWindow(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.qg = QtGui.QGraphicsView(self)
self.scene = QtGui.QGraphicsScene(self)
self.qg.setScene(self.scene)
# Make window fullscreen and always on top
self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
# set the image (lena)
qimg = q2n.array2qimage(np.pad(lena(), ((0,0),(0,0)), mode='constant'))
pix = QtGui.QPixmap(qimg)
self.scene.clear()
self.scene.addPixmap(pix)
styleSheetCss="QGraphicsView {border-width: 0px;}"
self.setStyleSheet(styleSheetCss)
self.show()
If there is another way to address this problem, I dunno, but this has worked for me.
Side note, you can also string css changes together-
styleSheetCss="""
QPushButton {color:#ffffff;background-color:#202020;padding:4px;border:1px solid #303030;}
QMenu {color:#ffffff;background-color:#505050;border:1px solid #282828;}
QMenu::item {color:#ffffff;background-color:#505050;padding:2px;}
QMenu::item:selected {color:#ffffff;background-color:#6c6c6c;padding:2px;}
QSlider {background-color:#323232;}
QScrollBar:vertical {width:10px;color:#ffffff;background-color:#808080;border:1px solid #202020;}"""
self.setStyleSheet(styleSheetCss)
Related
I made a QGraphicsTextItem and set plain text as its content. After that, I set the QGraphicsTextItem inside the QGraphicsWidget.
My question is, Is it possible to resize the QGraphicsTextItem including its text/contents like in this picture:
This is the video of the resizing that I'm asking for.
If this is possible, how can I apply it to the QGraphicsTextItem?
The first picture is the image of the QGraphicsTextItem but I have no idea how to implement the resizing in the video.
Things I've tried:
I tried using the setTextWidth() and setting it to 0.5 but it's not working.
I also tried using adjustSize() to the QGraphicsTextItem but it's also not working.
Code to reproduce the issue:
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.view = QGraphicsView()
scene = QGraphicsScene()
#before resizing
item = QGraphicsTextItem("Line 1 Line 2 Line 3")
item.setFlags(QGraphicsWidget.ItemIsSelectable)
item.setPos(self.view.mapToScene(2, 2))
scene.addItem(item)
#after resizing
item_1 = QGraphicsTextItem("Line 1\nLine 2\nLine 3")
item_1.setFlags(QGraphicsWidget.ItemIsSelectable)
item_1.setPos(self.view.mapToScene(2, 30))
scene.addItem(item_1)
self.view.setScene(scene)
self.setCentralWidget(self.view)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec_()
There have been similar questions asked about overriding the QCompleter popup position but i'll still not found a working solution. I simply want to move the popup down around 5px (I have some specific styling requirements)
I've tried subclassing a QListView and using that as my popup using setPopup(). I then override the showEvent and move the popup down in Y. I also do this on the resizeEvent since I believe this is triggered when items are filtered and the popup resizes. However this doesn't work.. I then used a singleshot timer to trigger the move after 1ms. This does kind of work but it seems quite inconsistent - the first time it shows is different to subsequent times or resizing.
Below is my latest attempt (trying to hack it by counting the number of popups..), hopefully someone can show me what i'm doing wrong or a better solution
import sys
import os
from PySide2 import QtCore, QtWidgets, QtGui
class QPopup(QtWidgets.QListView):
def __init__(self, parent=None):
super(QPopup, self).__init__(parent)
self.popups = 0
def offset(self):
y = 3 if self.popups < 2 else 7
print('y: {}'.format(y))
self.move(self.pos().x(), self.pos().y() + y)
self.popups += 1
def showEvent(self, event):
print('show')
# self.offset()
QtCore.QTimer.singleShot(1, self.offset)
def resizeEvent(self, event):
print('resize')
# self.offset()
QtCore.QTimer.singleShot(1, self.offset)
class MyDialog(QtWidgets.QDialog):
def __init__(self, parent=None):
super(MyDialog, self).__init__(parent)
self.create_widgets()
self.create_layout()
self.create_connections()
def create_widgets(self):
self.le = QtWidgets.QLineEdit('')
self.completer = QtWidgets.QCompleter(self)
self.completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.completer.setCompletionMode(QtWidgets.QCompleter.PopupCompletion)
self.completer.setMaxVisibleItems(10)
self.completer.setFilterMode(QtCore.Qt.MatchContains)
self.completer.setPopup(QPopup())
popup = QPopup(self)
self.completer.setPopup(popup)
self.model = QtCore.QStringListModel()
self.completer.setModel(self.model)
self.le.setCompleter(self.completer)
self.completer.model().setStringList(['one','two','three'])
def create_layout(self):
main_layout = QtWidgets.QVBoxLayout(self)
main_layout.addWidget(self.le)
def create_connections(self):
pass
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
my_dialog = MyDialog()
my_dialog.show() # Show the UI
sys.exit(app.exec_())
One solution could be to make a subclass of QLineEdit and override keyPressEvent to display the popup with an offset:
PySide2.QtWidgets.QCompleter.complete([rect=QRect()])
For PopupCompletion and QCompletion::UnfilteredPopupCompletion modes, calling this function displays the popup displaying the current completions. By default, if rect is not specified, the popup is displayed on the bottom of the widget() . If rect is specified the popup is displayed on the left edge of the rectangle.
see doc.qt.io -> QCompleter.complete.
Complete, self-contained example
The rect is calculated based on the y-position of the cursor rect. The height of the popup window is not changed. The width is adjusted to the width of the ZLineEdit widget.
rect = QtCore.QRect(0,
self.cursorRect().y() + 4,
self.width(),
self.completer().widget().height())
Your code, slightly modified using the points mentioned above, could look like this:
import sys
from PySide2 import QtCore, QtWidgets
from PySide2.QtWidgets import QLineEdit, QDialog, QCompleter
class ZLineEdit(QLineEdit):
def __init__(self, string, parent=None):
super().__init__(string, parent)
def keyPressEvent(self, event):
super().keyPressEvent(event)
if len(self.text()) > 0:
rect = QtCore.QRect(0,
self.cursorRect().y() + 4,
self.width(),
self.completer().widget().height())
self.completer().complete(rect)
class MyDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.le = ZLineEdit('')
autoList = ['one', 'two', 'three']
self.completer = QCompleter(autoList, self)
self.setup_widgets()
self.create_layout()
self.create_connections()
def setup_widgets(self):
self.completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.completer.setCompletionMode(QtWidgets.QCompleter.PopupCompletion)
self.completer.setMaxVisibleItems(10)
self.completer.setFilterMode(QtCore.Qt.MatchContains)
self.le.setCompleter(self.completer)
def create_layout(self):
main_layout = QtWidgets.QVBoxLayout(self)
main_layout.addWidget(self.le)
def create_connections(self):
pass
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
my_dialog = MyDialog()
my_dialog.show()
sys.exit(app.exec_())
Test
On the left side you see the default behavior. On the right side the popup is moved down 4px:
I would like to know how one can create a custom widget in pyqt. I've seen many different examples for C++, and a couple non descript examples for pyqt, but nothing that really explains how to do it and implement it. There is especially no examples that basically aren't just modified qt-designer output, and I'm writing my code from scratch so that's not very helpful.
So far, the best example I could find was basically just someone modifying qt-designer code and not really explaining what any of it was doing.
Could someone please show me an example of how to create a custom widget?
Edit:
I'm attempting to create a widget with an embedded QStackedWidget, and buttons on the bottom to cycle the pages.
I also planned on having a seperate widget for each page, but considering I can't actually accomplish step one, I figured I would cross that bridge when I get to it.
In the following it is shown how to implement a QStackedWidget with 2 buttons, the basic idea is to layout the design, for this we analyze that a QVBoxLayout must be placed to place the QStackedWidget and another layout, this second layout will be a QHBoxLayout to have the buttons. Then we connect the signals that handle the transition between pages. Also in this example I have created 3 types of widgets that will be placed on each page.
from PyQt5.QtWidgets import *
class Widget1(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent=parent)
lay = QVBoxLayout(self)
for i in range(4):
lay.addWidget(QPushButton("{}".format(i)))
class Widget2(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent=parent)
lay = QVBoxLayout(self)
for i in range(4):
lay.addWidget(QLineEdit("{}".format(i)))
class Widget3(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent=parent)
lay = QVBoxLayout(self)
for i in range(4):
lay.addWidget(QRadioButton("{}".format(i)))
class stackedExample(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent=parent)
lay = QVBoxLayout(self)
self.Stack = QStackedWidget()
self.Stack.addWidget(Widget1())
self.Stack.addWidget(Widget2())
self.Stack.addWidget(Widget3())
btnNext = QPushButton("Next")
btnNext.clicked.connect(self.onNext)
btnPrevious = QPushButton("Previous")
btnPrevious.clicked.connect(self.onPrevious)
btnLayout = QHBoxLayout()
btnLayout.addWidget(btnPrevious)
btnLayout.addWidget(btnNext)
lay.addWidget(self.Stack)
lay.addLayout(btnLayout)
def onNext(self):
self.Stack.setCurrentIndex((self.Stack.currentIndex()+1) % 3)
def onPrevious(self):
self.Stack.setCurrentIndex((self.Stack.currentIndex()-1) % 3)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
w = stackedExample()
w.show()
sys.exit(app.exec_())
Here are some nice advises, examples and approaches.
I think you can divide a custom Widget or any Custom "thing" you want in three ways.
Behavior: When you override its default methods with the behavior you want.
Layout: All the qt objects, be Items, or Widgets you add inside the layout will follow it's position rules and its policies.
StyleSheet: In case of Widget objects where you set the style of the Widget let's say setting its "CSS", just to be concise. Here are some references and examples.
Note: In case of non Widget objects you will not be able to set a StyleSheet so you will have to override some paint methods, create your own Painters and so on.
Here are some random examples with some comments along approaching the 3 topics I mentioned above:
import random
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QDialog
from PyQt5.QtWidgets import QHBoxLayout
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtWidgets import QVBoxLayout
from PyQt5.QtWidgets import QWidget
class MovableWidget(QWidget):
def __init__(self):
super(MovableWidget, self).__init__()
#remove the frame
self.setWindowFlags(Qt.CustomizeWindowHint)
self.pressing = False
# overriding the three next methods is a way to customize your Widgets
# not just in terms of appearance but also behavioral.
def mousePressEvent(self, QMouseEvent):
#the pos of the widget when you first pressed it.
self.start = QMouseEvent.pos()
#to make sure you are holding mouse button down
self.pressing = True
def mouseMoveEvent(self, QMouseEvent):
# You can Verify if it's also the left button and some other things
# you need.
if self.pressing : #and QMouseEvent.type() == Qt.LeftButton
self.end = QMouseEvent.pos()
self.delta = self.mapToGlobal(self.end-self.start)
self.move(self.delta)
self.end = self.start
def mouseReleaseEvent(self, QMouseEvent):
self.pressing = False
# inherits from QDialog and from MovableWidget so we can have its properties.
class CustomDialog(QDialog, MovableWidget):
def __init__(self):
super(CustomDialog, self).__init__()
#Make the Dialog transparent
self.setAttribute(Qt.WA_TranslucentBackground)
# the widget will dispose itself according to the layout rules he's
# inserted into.
self.inner_widget = QWidget()
self.inner_widget.setFixedSize(300,300)
self.inner_layout = QHBoxLayout()
self.inner_widget.setLayout(self.inner_layout)
self.btn_change_color = QPushButton("Roll Color")
self.btn_change_color.setStyleSheet("""
background-color: green;
""")
# will connect to a function to be executed when the button is clicked.
self.btn_change_color.clicked.connect(self.change_color)
self.inner_layout.addWidget(self.btn_change_color)
# Choose among many layouts according to your needs, QVBoxLayout,
# QHBoxLayout, QStackedLayout, ... you can set its orientation
# you can set its policies, spacing, margins. That's one of the main
# concepts you have to learn to customize your Widget in the way
# you want.
self.layout = QVBoxLayout()
# stylesheet have basically CSS syntax can call it QSS.
# it can be used only on objects that come from Widgets
# Also one of the main things to learn about customizing Widgets.
# Note: The stylesheet you set in the "father" will be applied to its
# children. Unless you tell it to be applied only to it and/or specify
# each children's style.
# The point I used inside the StyleSheet before the QDialog
# e.g .QDialog and .QWidget says it'll be applied only to that
# instance.
self.setStyleSheet("""
.QDialog{
border-radius: 10px;
}
""")
self.inner_widget.setStyleSheet("""
.QWidget{
background-color: red;
}
""")
self.layout.addWidget(self.inner_widget)
self.setLayout(self.layout)
def change_color(self):
red = random.choice(range(0,256))
green = random.choice(range(0,256))
blue = random.choice(range(0,256))
self.inner_widget.setStyleSheet(
"""
background-color: rgb({},{},{});
""".format(red,green,blue)
)
# since MovableWidget inherits from QWidget it also have QWidget properties.
class ABitMoreCustomizedWidget(MovableWidget):
def __init__(self):
super(ABitMoreCustomizedWidget, self).__init__()
self.layout = QHBoxLayout()
self.setLayout(self.layout)
self.custom_button1 = CustomButton("Button 1")
self.custom_button1.clicked.connect(self.btn_1_pressed)
self.custom_button2 = CustomButton("Button 2")
self.custom_button2.clicked.connect(self.btn_2_pressed)
self.layout.addWidget(self.custom_button1)
self.layout.addWidget(self.custom_button2)
def btn_1_pressed(self):
self.custom_button1.hide()
self.custom_button2.show()
def btn_2_pressed(self):
self.custom_button2.hide()
self.custom_button1.show()
class CustomButton(QPushButton):
# it could receive args and keys** so all the QPushButton initializer
# would work for here too.
def __init__(self, txt):
super(CustomButton, self).__init__()
self.setText(txt)
self.setStyleSheet("""
QPushButton{
background-color: black;
border-radius: 5px;
color: white;
}
QPushButton::pressed{
background-color: blue;
}
QPushButton::released{
background-color: gray;
}
""")
if __name__ == "__main__":
app = QApplication(sys.argv)
custom_dialog = CustomDialog()
custom_widget = ABitMoreCustomizedWidget()
custom_dialog.show()
custom_widget.show()
sys.exit(app.exec_())
Tips:
You are also able to make use of masks in your widget changing it's format in "crazy" ways. For example if you need a hollow ringed widget you can have a image with this format and some transparency, create a QPixMap from that and apply it as a mask to your widget. Not a trivial work but kind of cool.
Since I showed you examples with no "TopBar" with no Frame you can also have a look in this other question where I show how to create your own top bar, move around and resize concepts.
I'm trying to create a rich-text editor with a layout similar to Microsoft Word's 'Page View' or 'Print Layout.' I'd like to have a QTextEdit horizontally centered in the main window, with the scroll-bar aligned against the far right edge of the main window.
I couldn't find a way to move a QTextEdit's default scroll-bar independent of the QTextEdit itself. Instead, I tried creating a separate scroll-bar, and making the QTextEdit grow vertically using the solution found here: A QWidget like QTextEdit that wraps its height automatically to its contents?
Here is my attempt:
import sys
from PySide import QtGui, QtCore
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.initUI()
def initUI(self):
cw = CentralWidget()
self.setCentralWidget(cw)
self.setGeometry(200, 200, 1000, 600)
self.show()
def resizeEvent(self, event):
self.centralWidget().setFixedHeight(event.size().height())
class CentralWidget(QtGui.QWidget):
def __init__(self):
super(CentralWidget, self).__init__()
self.initUI()
def initUI(self):
text = MainTextEdit()
text.setMinimumWidth(850)
text.setStyleSheet('border: 0;')
pageWidget = QtGui.QWidget()
scroll = QtGui.QScrollArea()
scroll.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
scroll.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
scroll.setMaximumWidth(18)
# If you change setWidgetResizeable to False,
# the textedit will center, but scrolling will not work.
scroll.setWidgetResizable(True)
scroll.setWidget(pageWidget)
hbox = QtGui.QHBoxLayout()
hbox.setContentsMargins(0,0,0,0)
hbox.addStretch(0.5)
hbox.addWidget(text)
hbox.addStretch(0.5)
pageWidget.setLayout(hbox)
hbox2 = QtGui.QHBoxLayout()
hbox2.setContentsMargins(0,0,0,0)
hbox2.addWidget(pageWidget)
hbox2.addWidget(scroll)
self.setLayout(hbox2)
class MainTextEdit(QtGui.QTextEdit):
def __init__(self, *args, **kwargs):
super(MainTextEdit, self).__init__(*args, **kwargs)
self.document().contentsChanged.connect(self.sizeChange)
self.setFontPointSize(80)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
def sizeChange(self):
docHeight = self.document().size().height()
self.setMinimumHeight(docHeight)
def main():
app = QtGui.QApplication(sys.argv)
mw = MainWindow()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
There are at least two problems with this:
Problem #1
As is, the code above does not horizontally center the QTextEdit in the main window, but the scroll bar at the far-right does work. If you change scroll.setWidgetResizable(True) to scroll.setWidgetResizable(False) on line 41, the QTextEdit will center horizontally, but the scroll-bar does not work. It seems you can get one feature or the other, but not both.
Problem #2
In order to keep the MainWindow from auto-expanding when the QTextEdit grows, the MainWindow assigns a fixed height to the CentralWidget whenever the MainWindow is resized (see line 19 of the code above). This works well until the user tries to vertically shrink the main window. The window can be vertically expanded by clicking and dragging the bottom border, but it can't be vertically shrunk.
Conclusion
Maybe this is the wrong approach all-together. Any suggestions?
Set a symmetrical margin via setViewportMargins on the QTextEdit which inherits from QAbstractScrollArea.
Example:
from PySide import QtGui, QtCore
app = QtGui.QApplication([])
window = QtGui.QWidget()
layout = QtGui.QVBoxLayout(window)
edit = QtGui.QTextEdit('jfdh afdhgfkjg fdnvfh vklkfjvkflj lddkl ljklfjkl jvkldjfkvljfgvjldf ll dl dljvklj ljljlbl llkb jbgl')
edit.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
edit.setViewportMargins(30, 0, 30, 30)
layout.addWidget(edit)
window.show()
app.exec_()
Gives:
I'm developing a custom widget (inheriting from QWidget) to use as a control. How can I fix the aspect-ratio of the widget to be square, but still allow it to be resized by the layout manager when both vertical and horizontal space allows?
I know that I can set the viewport of the QPainter so that it only draws in a central square area, but that still allows the user to click either side of the drawn area.
It seems like there is no universal way to keep a widget square under all circumstances.
You must choose one:
Make its height depend on its width:
class MyWidget(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
policy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
policy.setHeightForWidth(True)
self.setSizePolicy(policy)
...
def heightForWidth(self, width):
return width
...
Make its minimal width depend on its height:
class MyWidget(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
...
def resizeEvent(self, e):
setMinimumWidth(height())
...
Such a widget will be kept square as long as there is such a possibility.
For other cases you should indeed consider changing the viewport, as you mentioned. Mouse events shouldn't be that much of a problem, just find the center of the widget (divide dimensions by 2), find min(width, height) and go from there. You should be able to validate the mouse events by coordinate. It is nice to call QMouseEvent.accept, only if the event passed the validation and you used the event.
I'd go with BlaXpirit's method, but here's an alternative that I've used before.
If you subclass the custom widget's resiseEvent() you can adjust the requested size to make it a square and then set the widget's size manually.
import sys
from PyQt4 import QtCore, QtGui
class CustomWidget(QtGui.QFrame):
def __init__(self, parent=None):
QtGui.QFrame.__init__(self, parent)
# Give the frame a border so that we can see it.
self.setFrameStyle(1)
layout = QtGui.QVBoxLayout()
self.label = QtGui.QLabel('Test')
layout.addWidget(self.label)
self.setLayout(layout)
def resizeEvent(self, event):
# Create a square base size of 10x10 and scale it to the new size
# maintaining aspect ratio.
new_size = QtCore.QSize(10, 10)
new_size.scale(event.size(), QtCore.Qt.KeepAspectRatio)
self.resize(new_size)
class MainWidget(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
layout = QtGui.QVBoxLayout()
self.custom_widget = CustomWidget()
layout.addWidget(self.custom_widget)
self.setLayout(layout)
app = QtGui.QApplication(sys.argv)
window = MainWidget()
window.show()
sys.exit(app.exec_())