I have a small application written in python that I want to move from GTK+ to Qt.
The graphics interface in the GTK version is basically a tab widget (gtk.Notebook) that fills the whole top level window. The tab window grows and shrinks with the top level window and fills it completely.
In GTK the code looks like:
...
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
...
self.notebook = gtk.Notebook()
self.window.add(self.notebook)
...
How to do something similar in Qt? I just can't figure it out! For the GTK code I used no graphics tool, but now I'm trying to use Qt designer.
JW
This is how you would get a basic QTabWidget set up:
from PyQt4.QtCore import (Qt, SIGNAL)
from PyQt4.QtGui import (QApplication, QDialog,
QVBoxLayout, QPushButton, QTabWidget, QWidget, )
class Form(QWidget):
def __init__(self, parent=None):
super(Form, self).__init__(parent)
self.tabauto = QWidget() #set up 'auto' tab
self.tabman = QWidget() #set up 'manual' tab
self.tabs = QTabWidget() #set up tabs widget
self.ButtonM = QPushButton("Manual Button")
self.ButtonA = QPushButton("AUto Button")
layoutO = QVBoxLayout() #set overal layout
layoutA = QVBoxLayout()
layoutA.addWidget(self.ButtonA)
layoutM = QVBoxLayout()
layoutM.addWidget(self.ButtonM)
self.tabman.setLayout(layoutM) #Add manual layout to manual tab
self.tabauto.setLayout(layoutA) #Add automatic layout to automatic tab
self.tabs.addTab(self.tabauto, "Auto") #assign tabs with their layouts to the overall tab widget
self.tabs.addTab(self.tabman, "Manual") #assign tabs with their layouts to the overall tab widget
layoutO.addWidget(self.tabs) #add overall tab widget to overall layout
self.setLayout(layoutO) #make the overall layout visible
app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()
Related
How do I create a drop-down widget, such as a drop-down QLabel, drop-down QTextBrowser, etc.?
For example, I log information in a QTextBrowser, but I don't want it taking up space on the screen. So I want to be able to click a QToolbutton and have a scrollable QTextBrowser drop-down. (A QComboBox would work too, but I can't just add each event as a separate item - I need the text to wrap, not be elided. Thus a drop-down QTextBrowser.)
Or, for example, I want a drop-down QLabel containing a picture, etc...
Create a QWidgetAction for the drop-down widget, and add it to the tool-button's menu:
from PyQt4 import QtGui, QtCore
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
layout = QtGui.QHBoxLayout(self)
self.button = QtGui.QToolButton(self)
self.button.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
self.button.setMenu(QtGui.QMenu(self.button))
self.textBox = QtGui.QTextBrowser(self)
action = QtGui.QWidgetAction(self.button)
action.setDefaultWidget(self.textBox)
self.button.menu().addAction(action)
layout.addWidget(self.button)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.resize(100, 60)
window.show()
sys.exit(app.exec_())
I've got a PyQt GUI with a QTextEdit in it. I have set a few of the widget settings to play with things like the font size. What I'm seeing is that when I initially type in the field, the settings are applied, but if I delete all text and start typing again, the settings have reset to the default ones. Below is a MWE where I can see this behavior. Just in case it matters, I'm using Python 3.5.1 with PyQt4 4.8.7.
from PyQt4 import QtCore, QtGui
class App(object):
def __init__(self):
self.app = QtGui.QApplication([]) # The main application
self.win = QtGui.QMainWindow() # The main window
self.widget = QtGui.QWidget() # The central widget in the main window
self.grid = QtGui.QVBoxLayout() # The layout manager of the central widget
self.textArea = QtGui.QTextEdit()
self.grid.addWidget(self.textArea)
self.textArea.setMinimumSize(600,300)
self.textArea.setLineWrapMode(QtGui.QTextEdit.NoWrap)
self.textArea.setFontPointSize(12)
self.widget.setLayout(self.grid)
self.win.setCentralWidget(self.widget)
self.win.show()
self.app.exec_()
App()
You can create a new QFont item and then you can use QTextEdit.setFont()
This way it will not reset after all text is deleted.
I had an application that contained a lot of widgets with stylesheet on them, However, I did not add any layout to interface, It neither had central widget included, But the application was running without any problems.
However, whenever i tried to resize the application (scaling it down) the widgets would not scale, of course.
I had an little research (Because i could not find anything else related to my problem) and i found this on Qt Documentation, stylesheet reference:
"The actual image that is drawn is determined using the same algorithm as QIcon (i.e) the image is never scaled up but always scaled down if necessary."
How can i make stylesheet scale down with window? (If stylesheet has background image on)
For example i have button with stylesheet:
btn = QtGui.QPushButton(self)
btn.move(0, 0)
btn.setObjectName('btn)
btn.setStyleSheet("#btn {background-image: url(':/images/somepicture.png'); border: none; }")
How can i make this button scale down with window, Can i achieve this without layouts? If not how can i do it with layouts? (without it limiting too much)
If you add the button as the central widget to a QMainWindow it should automatically adjust it's size to fit the available space. However, to get the button image to scale, you need to set the image as a border-image stylesheet property (a little strange). A working example for PyQt4:
from PyQt4 import QtGui, QtCore
class MainWindow(QtGui.QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
btn = QtGui.QPushButton(self)
btn.setStyleSheet("border-image: url('somepicture.png');") # Scaled
#btn.setStyleSheet("background-image: url('somepicture.png');") # Not scaled
self.setCentralWidget(btn)
self.show()
app = QtGui.QApplication([])
window = MainWindow()
app.exec_()
Note that you don't need to set an id (objectName) to assign the CSS to a specific widget, you can simply pass in the CSS rule via .setStyleSheet().
You cannot set a layout on QMainWindow as it already has a complex layout system to accommodate docking widgets and toolbars. Therefore, if you want to use a layout to add more than one widget to the window, you need to use a container widget to hold it. The following working example demonstrates this:
from PyQt4 import QtGui, QtCore
class MainWindow(QtGui.QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
w = QtGui.QWidget() # container widget
l = QtGui.QVBoxLayout() # your layout
w.setLayout(l) # set the layout on your container widget
btn = QtGui.QPushButton(self)
btn.setStyleSheet("border-image: url('somepicture.png');")
label = QtGui.QLabel('Hello!')
l.addWidget(btn) # add your widget to the layout
l.addWidget(label) # add the label to the layout
self.setCentralWidget(w) # add the container widget to the QMainWindow
self.show()
app = QtGui.QApplication([])
window = MainWindow()
app.exec_()
If you want to be able to position widgets absolutely, rather than adding them to a layout (which will control their size/position) you can pass the parent element (relative to which x,y coords are taken) when creating it:
from PyQt4 import QtGui, QtCore
class MainWindow(QtGui.QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
w = QtGui.QWidget() # container widget
btn = QtGui.QPushButton(w)
btn.move(100,100)
btn.setStyleSheet("border-image: url('somepicture.png');")
self.setCentralWidget(w) # add the container widget to the QMainWindow
self.show()
app = QtGui.QApplication([])
window = MainWindow()
app.exec_()
But positioning a widget absolutely like this loses you the ability to auto-scale it to fit the parent widget. If you just want some padding/spacing around the element in the window, take a look at .setContentsMargins on the QLayouts, e.g. l.setContentsMargins(50,50,50,50) will put a 50px margin around the button.
I want to implement a GUI program like the blueprint editor in the Unreal game engine with PyQt4. Here is an example of the blueprint editor:
First I create a simple container widget to place all the components(The rectangles). In order to allow the user place the rectangles wherever they want(by drag & drop), I can't place my widgets in a layout. Then when the content of the rectangle is changed, the rectangle widget can't auto adjust the size itself.
Following is an example code:
import sys
from PyQt4 import QtCore
from PyQt4 import QtGui
class ChangeableChild(QtGui.QWidget):
def __init__(self, parent=None):
super(ChangeableChild, self).__init__(parent)
self.setLayout(QtGui.QVBoxLayout())
def addWidget(self, widget):
self.layout().addWidget(widget)
class MainWidget(QtGui.QWidget):
def __init__(self, child, parent=None):
super(MainWidget, self).__init__(parent)
child.setParent(self)
def main():
app = QtGui.QApplication(sys.argv)
changeable_child = ChangeableChild()
button = QtGui.QPushButton("Add label")
changeable_child.addWidget(button)
win = MainWidget(changeable_child)
win.show()
button.clicked.connect(
lambda: changeable_child.addWidget(QtGui.QLabel("A label.")))
app.exec_()
if __name__ == "__main__":
main()
When I hit "Add label" button to add a new label. The size of ChangeableChild wouldn't change automatically. If I put the ChangeableChild in a layout, it's all good.
So is there a way to auto adjust my widget when it's not in a layout? Or is there a way I can place my widget in a layout and still can place it in a absolute position?
How do I create a drop-down widget, such as a drop-down QLabel, drop-down QTextBrowser, etc.?
For example, I log information in a QTextBrowser, but I don't want it taking up space on the screen. So I want to be able to click a QToolbutton and have a scrollable QTextBrowser drop-down. (A QComboBox would work too, but I can't just add each event as a separate item - I need the text to wrap, not be elided. Thus a drop-down QTextBrowser.)
Or, for example, I want a drop-down QLabel containing a picture, etc...
Create a QWidgetAction for the drop-down widget, and add it to the tool-button's menu:
from PyQt4 import QtGui, QtCore
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
layout = QtGui.QHBoxLayout(self)
self.button = QtGui.QToolButton(self)
self.button.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
self.button.setMenu(QtGui.QMenu(self.button))
self.textBox = QtGui.QTextBrowser(self)
action = QtGui.QWidgetAction(self.button)
action.setDefaultWidget(self.textBox)
self.button.menu().addAction(action)
layout.addWidget(self.button)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.resize(100, 60)
window.show()
sys.exit(app.exec_())