PyQt5 fix Qlabel position - pyqt

i am new to PyQt5 and I try to create a window with grid layout for buttons. But I want to add two labels at top left and bottom right corner of the window.
from PyQt5 import QtWidgets
from PyQt5 import QtCore
import sys
class PrettyWidget(QtWidgets.QWidget):
def __init__(self):
super(PrettyWidget, self).__init__()
self.initUI()
def initUI(self):
self.setGeometry(600,300, 1000, 600)
self.setWindowTitle('Program v1.0')
# Grid Layout
grid = QtWidgets.QGridLayout()
self.setLayout(grid)
self.lbl1 = QtWidgets.QLabel(self)
self.lbl1.setText('Author Information and Copy Right')
self.lbl1.adjustSize()
self.lbl1.move(588, 0)
# Label indicator
self.lbl2 = QtWidgets.QLabel(self)
self.lbl2.setText('Click import to start...')
self.lbl2.adjustSize()
self.lbl2.move(0, 0)
# Import data Button
btn1 = QtWidgets.QPushButton('Select Data', self)
btn1.resize(btn1.sizeHint())
btn1.clicked.connect(self.getData)
grid.addWidget(btn1, 0, 0)
# Import names Button
btn2 = QtWidgets.QPushButton('Select Names', self)
btn2.resize(btn2.sizeHint())
btn2.clicked.connect(self.getNames)
grid.addWidget(btn2, 0, 1)
# Run Button
btn3 = QtWidgets.QPushButton('Run', self)
btn3.resize(btn3.sizeHint())
btn3.clicked.connect(self.Run)
grid.addWidget(btn3, 1, 0)
# Save Button
btn4 = QtWidgets.QPushButton('Save',self)
btn4.resize(btn4.sizeHint())
btn4.clicked.connect(self.Save)
grid.addWidget(btn4, 1, 1)
self.show()
def getData(self):
self.lbl2.setText('Data selected!')
self.lbl2.adjustSize()
def getNames(self):
self.lbl2.setText('Names selected!')
self.lbl2.adjustSize()
def Run(self):
self.lbl2.setText('Done!')
self.lbl2.adjustSize()
def Save(self):
self.lbl2.setText('Saved!')
self.lbl2.adjustSize()
def main():
app = QtWidgets.QApplication(sys.argv)
w = PrettyWidget()
app.exec_()
if __name__ == '__main__':
main()
As you can see I use absolute position for two labels now. So when I maximize or change the window size, the label stays at the same position. How do I stick lbl1 at bottom right and lbl at top left as always?

Paste the labels into the layout.
Set the stretch factor of row row to stretch .
import sys
from PyQt5 import QtWidgets
from PyQt5 import QtCore
class PrettyWidget(QtWidgets.QWidget):
def __init__(self):
super(PrettyWidget, self).__init__()
self.initUI()
def initUI(self):
self.setGeometry(300,100, 1000, 600)
self.setWindowTitle('Program v1.0')
# Grid Layout
grid = QtWidgets.QGridLayout()
self.setLayout(grid)
self.lbl1 = QtWidgets.QLabel(self, alignment=QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
self.lbl1.setText('Author Information and Copy Right')
self.lbl1.adjustSize()
grid.addWidget(self.lbl1, 0, 0)
grid.setRowStretch(1, 1) # <---- Sets the stretch factor of row row to stretch .
# Label indicator
self.lbl2 = QtWidgets.QLabel(self, alignment=QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
self.lbl2.setText('Click import to start...')
self.lbl2.adjustSize()
grid.addWidget(self.lbl2, 5, 1)
# Import data Button
btn1 = QtWidgets.QPushButton('Select Data', self)
btn1.resize(btn1.sizeHint())
btn1.clicked.connect(self.getData)
grid.addWidget(btn1, 2, 0)
# Import names Button
btn2 = QtWidgets.QPushButton('Select Names', self)
btn2.resize(btn2.sizeHint())
btn2.clicked.connect(self.getNames)
grid.addWidget(btn2, 2, 1)
# Run Button
btn3 = QtWidgets.QPushButton('Run', self)
btn3.resize(btn3.sizeHint())
btn3.clicked.connect(self.Run)
grid.addWidget(btn3, 3, 0)
# Save Button
btn4 = QtWidgets.QPushButton('Save',self)
btn4.resize(btn4.sizeHint())
btn4.clicked.connect(self.Save)
grid.addWidget(btn4, 3, 1)
grid.setRowStretch(4, 1) # <---- Sets the stretch factor of row row to stretch .
self.show()
def getData(self):
self.lbl2.setText('Data selected!')
self.lbl2.adjustSize()
def getNames(self):
self.lbl2.setText('Names selected!')
self.lbl2.adjustSize()
def Run(self):
self.lbl2.setText('Done!')
self.lbl2.adjustSize()
def Save(self):
self.lbl2.setText('Saved!')
self.lbl2.adjustSize()
def main():
app = QtWidgets.QApplication(sys.argv)
w = PrettyWidget()
app.exec_()
if __name__ == '__main__':
main()

Related

How to add scrollable regions with Drag & drop widgets with PyQt?

Please add a scrollable region to this code so that when I run the code, I can scroll down through the window and see the last items in the window and replace them.
As this is a drag and drop code I could not add scroll to it.
Moreover, during the drag and drop process, the scroll should work and does not interrupt the drag and drop process.
from PyQt5.QtWidgets import QApplication, QScrollArea, QHBoxLayout, QWidget, QLabel, QMainWindow, QVBoxLayout
from PyQt5.QtCore import Qt, QMimeData, pyqtSignal
from PyQt5.QtGui import QDrag, QPixmap
class DragItem(QLabel):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setContentsMargins(25, 5, 25, 5)
self.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.setStyleSheet("border: 1px solid black;")
# Store data separately from display label, but use label for default.
self.data = self.text()
def set_data(self, data):
self.data = data
def mouseMoveEvent(self, e):
if e.buttons() == Qt.LeftButton:
drag = QDrag(self)
mime = QMimeData()
drag.setMimeData(mime)
pixmap = QPixmap(self.size())
self.render(pixmap)
drag.setPixmap(pixmap)
drag.exec_(Qt.MoveAction)
class DragWidget(QWidget):
"""
Generic list sorting handler.
"""
orderChanged = pyqtSignal(list)
def __init__(self, *args, orientation=Qt.Orientation.Horizontal, **kwargs):
super().__init__()
self.setAcceptDrops(True)
# Store the orientation for drag checks later.
self.orientation = orientation
if self.orientation == Qt.Orientation.Vertical:
self.blayout = QVBoxLayout()
else:
self.blayout = QHBoxLayout()
self.setLayout(self.blayout)
def dragEnterEvent(self, e):
e.accept()
def dropEvent(self, e):
pos = e.pos()
widget = e.source()
for n in range(self.blayout.count()):
# Get the widget at each index in turn.
w = self.blayout.itemAt(n).widget()
if self.orientation == Qt.Orientation.Vertical:
# Drag drop vertically.
drop_here = pos.y() < w.y() + w.size().height() // 2
else:
# Drag drop horizontally.
drop_here = pos.x() < w.x() + w.size().width() // 2
if drop_here:
# We didn't drag past this widget.
# insert to the left of it.
self.blayout.insertWidget(n-1, widget)
self.orderChanged.emit(self.get_item_data())
break
e.accept()
def add_item(self, item):
self.blayout.addWidget(item)
def get_item_data(self):
data = []
for n in range(self.blayout.count()):
# Get the widget at each index in turn.
w = self.blayout.itemAt(n).widget()
data.append(w.data)
return data
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.drag = DragWidget(orientation=Qt.Orientation.Vertical)
self.scroll = QScrollArea() ###########
self.blayout = QHBoxLayout()
self.widget = QWidget()
for n, l in enumerate(['Art', 'Boo', 'EOA', 'Hel', \
'Hyg', 'Lei', 'Lei','Lei','Lei','Lei','Lei','Lei','Lei','Lei','Lei','Lei','Lei', 'Med',\
'Nut','Nut','Nut','Rel','Rel','Rel','Sle','SLN','Spo','Spo','Spo','Spo','Spo','Thi','Thi',\
'Wor','Wor','Wor','Wor','Wor','Wor','Wor','Wor','Wor','Wor','Wor','Wor','Wor','Wor']):
item = DragItem(l)
item.set_data(n) # Store the data.
self.drag.add_item(item)
def myFun():
print('hi', self.drag.get_item_data())
# Print out the changed order.
# self.drag.orderChanged.connect(print)
# add by me
self.drag.orderChanged.connect(myFun)
#Scroll Area Properties
self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.scroll.setWidgetResizable(True)
self.scroll.setWidget(self.widget)
container = QWidget()
layout = QVBoxLayout()
layout.addStretch(1)
layout.addWidget(self.drag)
layout.addStretch(1)
container.setLayout(layout)
self.setCentralWidget(container)
# self.setCentralWidget(self.scroll)
app = QApplication([])
w = MainWindow()
w.show()
app.exec_()

PyQt: Is it possible to drag/drop QWidgets in a QGridLayout to rearrange them?

I am looking for a way to create a grid of graphs that can be dragged/dropped to rearrange the order. My first try was using QDockWidgets as they allow for drag/drop, however they were limited in a lot of other ways. Would it be possible to implement this function in a QGridLayout?
For now I have a QGridLayout with 3x3 matplotlib widgets.
Here is an example of the desired layout outcome.
Sample code:
import sys
from PyQt5 import QtWidgets
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
import random
from PyQt5.QtWidgets import QGridLayout, QVBoxLayout, QHBoxLayout, QScrollArea, QWidget, QDialog, QApplication, QFrame
class IndicSelectWindow(QDialog):
def __init__(self, parent=None):
super(IndicSelectWindow, self).__init__(parent=parent)
self.resize(1000, 800)
self.layout = QtWidgets.QHBoxLayout(self)
self.scrollArea = QScrollArea(self)
self.scrollArea.setWidgetResizable(True)
self.scrollAreaWidgetContents = QWidget()
self.gridLayout = QGridLayout(self.scrollAreaWidgetContents)
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
self.layout.addWidget(self.scrollArea)
for i in range(3):
for j in range(3):
self.Frame = QFrame(self)
self.Frame.setStyleSheet("background-color: white;")
self.Frame.setFrameStyle(QFrame.Panel | QFrame.Raised)
self.Frame.setLineWidth(2)
self.layout = QHBoxLayout(self.Frame)
self.figure = Figure() # a figure to plot on
self.canvas = FigureCanvas(self.figure)
self.ax = self.figure.add_subplot(111) # create an axis
data = [random.random() for i in range(10)]
self.ax.plot(data, '*-') # plot data
self.canvas.draw() # refresh canvas
self.layout.addWidget(self.canvas)
Box = QVBoxLayout()
Box.addWidget(self.Frame)
self.gridLayout.addLayout(Box, i, j)
self.gridLayout.setColumnStretch(i % 3, 1)
self.gridLayout.setRowStretch(j, 1)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = IndicSelectWindow()
w.show()
sys.exit(app.exec_())
Here is an implementation that will swap the positions of the items involved in a drag/drop. The 3 main steps are:
(1) Reimplement mousePressEvent to get the index of the LayoutItem based on mouse coordinates.
(2) Reimplement mouseMoveEvent to set up a QDrag of the FigureCanvas.
(3) Reimplement dropEvent to swap the target items in the layout.
Since the matplotlib widgets absorb mouse events you also need to reimplement eventFilter to detect them.
import sys, random
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
class IndicSelectWindow(QDialog):
def __init__(self, parent=None):
super(IndicSelectWindow, self).__init__(parent=parent)
self.resize(1000, 800)
self.target = None
self.setAcceptDrops(True)
self.layout = QHBoxLayout(self)
self.scrollArea = QScrollArea(self)
self.scrollArea.setWidgetResizable(True)
self.scrollAreaWidgetContents = QWidget()
self.gridLayout = QGridLayout(self.scrollAreaWidgetContents)
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
self.layout.addWidget(self.scrollArea)
for i in range(3):
for j in range(3):
self.Frame = QFrame(self)
self.Frame.setStyleSheet("background-color: white;")
self.Frame.setFrameStyle(QFrame.Panel | QFrame.Raised)
self.Frame.setLineWidth(2)
self.layout = QHBoxLayout(self.Frame)
self.figure = Figure() # a figure to plot on
self.canvas = FigureCanvas(self.figure)
self.ax = self.figure.add_subplot(111) # create an axis
data = [random.random() for i in range(10)]
self.ax.plot(data, '*-') # plot data
self.canvas.draw() # refresh canvas
self.canvas.installEventFilter(self)
self.layout.addWidget(self.canvas)
Box = QVBoxLayout()
Box.addWidget(self.Frame)
self.gridLayout.addLayout(Box, i, j)
self.gridLayout.setColumnStretch(i % 3, 1)
self.gridLayout.setRowStretch(j, 1)
def eventFilter(self, watched, event):
if event.type() == QEvent.MouseButtonPress:
self.mousePressEvent(event)
elif event.type() == QEvent.MouseMove:
self.mouseMoveEvent(event)
elif event.type() == QEvent.MouseButtonRelease:
self.mouseReleaseEvent(event)
return super().eventFilter(watched, event)
def get_index(self, pos):
for i in range(self.gridLayout.count()):
if self.gridLayout.itemAt(i).geometry().contains(pos) and i != self.target:
return i
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.target = self.get_index(event.windowPos().toPoint())
else:
self.target = None
def mouseMoveEvent(self, event):
if event.buttons() & Qt.LeftButton and self.target is not None:
drag = QDrag(self.gridLayout.itemAt(self.target))
pix = self.gridLayout.itemAt(self.target).itemAt(0).widget().grab()
mimedata = QMimeData()
mimedata.setImageData(pix)
drag.setMimeData(mimedata)
drag.setPixmap(pix)
drag.setHotSpot(event.pos())
drag.exec_()
def mouseReleaseEvent(self, event):
self.target = None
def dragEnterEvent(self, event):
if event.mimeData().hasImage():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
if not event.source().geometry().contains(event.pos()):
source = self.get_index(event.pos())
if source is None:
return
i, j = max(self.target, source), min(self.target, source)
p1, p2 = self.gridLayout.getItemPosition(i), self.gridLayout.getItemPosition(j)
self.gridLayout.addItem(self.gridLayout.takeAt(i), *p2)
self.gridLayout.addItem(self.gridLayout.takeAt(j), *p1)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = IndicSelectWindow()
w.show()
sys.exit(app.exec_())

Aligning QGridLayout rows in QScrollArea

I am trying to create a lot of rows in a PyQt5 grid widget, but they try to expand as much as they can. How can I set a fixed cell height? They are represented like this:
But I would like them to stick at the top, ordered like this:
Code:
name = QtWidgets.QLabel()
name.setText(str(ui.nombre.toPlainText()) + "({}, {}, {})".format(do, cota, alejamiento))
borrar = QtWidgets.QPushButton()
borrar.setText("X")
borrar.clicked.connect(self.borrar)
ui.elementos.addWidget(name, self.num_elementos, 0, 1, 1)
ui.elementos.addWidget(borrar, self.num_elementos, 1, 1, 1)
self.num_elementos += 1
self.update()
print(self.puntos)
And the elementos widget is created in other class:
self.scroll = QtWidgets.QScrollArea(self.gridLayoutWidget_2)
self.scroll_widget = QtWidgets.QWidget()
self.scroll_widget.resize(200, 700)
self.elementos = QtWidgets.QGridLayout()
self.scroll_widget.setLayout(self.elementos)
self.scroll.setWidget(self.scroll_widget)
self.Punto.addWidget(self.scroll, 4, 0, 1, 3)
You need to add a stretchable space beneath the rows of widgets, so that it pushes them all up to the top. One way to do this is to put another widget inside the scroll-widget, and then use a vertical layout to add the spacer. It will also help if you make the scroll-widget resizable, otherwise the rows will start to get squashed if too many are added.
Below is a demo that implements all that. Hopefully it should be clear how you can adapt this to work with your own code:
import sys
from PyQt5 import QtCore, QtWidgets
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.scroll = QtWidgets.QScrollArea()
self.scroll.setWidgetResizable(True)
self.scroll_widget = QtWidgets.QWidget()
self.scroll_widget.setMaximumWidth(200)
self.elementos_widget = QtWidgets.QWidget()
vbox = QtWidgets.QVBoxLayout(self.scroll_widget)
vbox.setContentsMargins(0, 0, 0, 0)
vbox.addWidget(self.elementos_widget)
vbox.addStretch()
self.elementos = QtWidgets.QGridLayout()
self.elementos_widget.setLayout(self.elementos)
self.scroll.setWidget(self.scroll_widget)
self.button = QtWidgets.QPushButton('Add')
self.button.clicked.connect(self.crear_punto)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.scroll)
layout.addWidget(self.button)
def crear_punto(self):
num_elementos = self.elementos.rowCount()
name = QtWidgets.QLabel()
name.setText('FOO %s' % num_elementos)
borrar = QtWidgets.QPushButton()
borrar.setText('X')
self.elementos.addWidget(name, num_elementos, 0)
self.elementos.addWidget(borrar, num_elementos, 1)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 100, 300, 500)
window.show()
sys.exit(app.exec_())

Get ID of dynamically created button when clicked

I have a program that dynamically creates tabs with buttons on them, when the user clicks button, I want it to give me the button_id (number that corresponds to the tab index).
I understand that you can do something like tabwidget.currentIndex() to get index of tab being used, but I don't want that as I will eventually have a method that iterates through the number of tabs and access each button without selecting the tabs as shown below.
for i in range(1,self.tabWidget.count()):
self.tabWidget.widget(i).stagematch.click()
For example:
If user clicks 'Clear Text' button on 'Tab 2' then I want it to give me the number 2 back.
How can I accomplish this without using the currentIndex() method for the tabs
Test code:
import sys
from PyQt5 import QtCore, QtWidgets
class TabPage(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
group = QtWidgets.QGroupBox('Monty Python')
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(group)
grid = QtWidgets.QGridLayout(group)
testbutton = QtWidgets.QPushButton('Clear Text')
grid.addWidget(testbutton, 2, 2)
testbutton.clicked.connect(self.tab_match)
#testbutton.clicked.connect(self.button_id)
def button_id(self):
sender = self.sender()
print(sender.text()) # Gives text of button, i'd like a number that corresponds to the tab# that called it
def tab_match(self,button_id):
#Do something with button ID here
pass
class Window(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.tabs = QtWidgets.QTabWidget()
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.tabs)
button = QtWidgets.QToolButton()
button.setToolTip('Add New Tab')
button.clicked.connect(self.addNewTab)
button.setIcon(self.style().standardIcon(
QtWidgets.QStyle.SP_DialogYesButton))
self.tabs.setCornerWidget(button, QtCore.Qt.TopRightCorner)
self.addNewTab()
def addNewTab(self):
text = 'Tab %d' % (self.tabs.count() + 1)
self.tabs.addTab(TabPage(self.tabs), text)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.setGeometry(600, 100, 300, 200)
window.show()
sys.exit(app.exec_())
Try it:
import sys
from PyQt5 import QtCore, QtWidgets
class TabPage(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.parent = parent # +
self.button_id = 0 # +
group = QtWidgets.QGroupBox('Monty Python')
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(group)
grid = QtWidgets.QGridLayout(group)
testbutton = QtWidgets.QPushButton('Clear Text')
grid.addWidget(testbutton, 2, 2)
testbutton.clicked.connect(self.tab_match)
self.parent.currentChanged.connect(self.qtabwidget_currentchanged) # +
def tab_match(self):
#Do something with button ID here
print("\ndef tab_match: button_id-> {}".format(self.button_id)) # +
#QtCore.pyqtSlot(int)
def qtabwidget_currentchanged(self, index): # +
self.button_id = index
class Window(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.tabs = QtWidgets.QTabWidget()
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.tabs)
button = QtWidgets.QToolButton()
button.setToolTip('Add New Tab')
button.clicked.connect(self.addNewTab)
button.setIcon(self.style().standardIcon(
QtWidgets.QStyle.SP_DialogYesButton))
self.tabs.setCornerWidget(button, QtCore.Qt.TopRightCorner)
self.button_id = 0
self.addNewTab()
def addNewTab(self):
text = 'Tab %d' % (self.tabs.count() + 1)
self.tabs.addTab(TabPage(self.tabs), text)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.setGeometry(600, 100, 300, 200)
window.show()
sys.exit(app.exec_())

How to add TextEdit, Labels and Buttons that move when Window Size is moved using PyQt?

I am new to PyQt, but for the past days I was trying to create a GUI which has labels, TextEdit and buttons which move when the Window size is moved (minimized or enlarged), I tried doing it so but the Buttons get stuck in the top left corner while the labels and TextEdit completely don't show up on the form, Please do help . Here is a snippet of my codes
import sys
from PyQt4 import QtGui, QtCore
class Window(QtGui.QMainWindow, QtGui.QWidget):
` def __init__(self):
super(Window, self).__init__()
self.setGeometry(50, 50, 500, 300)
self.setWindowTitle("PTE")
self.setWindowIcon(QtGui.QIcon('.png'))
self.center()
# Adding Menu to the GUI
quitAction = QtGui.QAction(QtGui.QIcon('exit.png'), "&Quit", self)
quitAction.setShortcut("Ctrl+Q")
quitAction.setStatusTip('Exit Application')
quitAction.triggered.connect(self.close_application)
undoAction = QtGui.QAction(QtGui.QIcon('undo.png'), "&Undo", self)
undoAction.setShortcut("Ctrl+Z")
undoAction.triggered.connect(self.close_application)
aboutAction = QtGui.QAction("&About PTE...", self)
self.statusBar()
#Actual Main Menu with options
mainMenu = self.menuBar()
fileMenu = mainMenu.addMenu('&File')
fileMenu.addAction(quitAction)
fileMenu = mainMenu.addMenu('&Edit')
fileMenu.addAction(undoAction)
fileMenu = mainMenu.addMenu('&Help')
fileMenu.addAction(aboutAction)
self.home()
#Centering Window on the screen
def center(self):
gui = self.frameGeometry()
cp = QtGui.QDesktopWidget().availableGeometry().center()
gui.moveCenter(cp)
self.move(gui.topLeft())
def home(self):
#Buttons
qbtn = QtGui.QPushButton('Quit', self)
qbtn.clicked.connect(self.close_application)
rbtn = QtGui.QPushButton("Run", self)
rbtn.clicked.connect(self.close_application)
hbox = QtGui.QHBoxLayout()
hbox.addStretch(1)
hbox.addWidget(qbtn)
hbox.addWidget(rbtn)
vbox = QtGui.QVBoxLayout()
vbox.addStretch(1)
vbox.addLayout(hbox)
self.setLayout(vbox)
self.show()
#Labels and TextBox
Intervals = QtGui.QLabel('Number of intervals (0<=20) :')
Timesteps = QtGui.QLabel('Number of time steps (<=1000) : ')
IntervalsEdit = QtGui.QLineEdit()
TimestepsEdit = QtGui.QLineEdit()
grid = QtGui.QGridLayout()
grid.setSpacing(2)
grid.addWidget(Intervals, 1, 0)
grid.addWidget(IntervalsEdit, 1, 1)
grid.addWidget(Timesteps, 2, 0)
grid.addWidget(TimestepsEdit, 2, 1)
self.setLayout(grid)
self.show()
#What to display when the app is closed
def close_application(self):
#Popup message before closing the application in Binary
choice = QtGui.QMessageBox.question(self, 'Message',"Are you sure you want to exit?",
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No )
if choice == QtGui.QMessageBox.Yes:
print(" Until Next Time")
sys.exit()
else:
pass
def run():
app = QtGui.QApplication(sys.argv)
GUI = Window()
sys.exit(app.exec_())
run()
Hey i fixed the issues with your code. In my fix, i added the QGridLayout to the QHBoxLayout. If you want the grid in another place you might need to nest both layouts in a 3rd layout.
Note that you are using setLayout for grid and for vbox when you can only set 1 layout. You also call show() twice, which you don't need. You also add a QVBoxLayout to hbox but do not add any widget. As it is, this is useless. If you want hbox and grid to be vertically aligned you will need to vbox.addLayout(grid) and self.setLayout(vbox) instead.
import sys
from PyQt4 import QtGui, QtCore
class Window(QtGui.QMainWindow, QtGui.QWidget):
` def __init__(self):
super(Window, self).__init__()
self.setGeometry(50, 50, 500, 300)
self.setWindowTitle("PTE")
self.setWindowIcon(QtGui.QIcon('.png'))
self.center()
# Adding Menu to the GUI
quitAction = QtGui.QAction(QtGui.QIcon('exit.png'), "&Quit", self)
quitAction.setShortcut("Ctrl+Q")
quitAction.setStatusTip('Exit Application')
quitAction.triggered.connect(self.close_application)
undoAction = QtGui.QAction(QtGui.QIcon('undo.png'), "&Undo", self)
undoAction.setShortcut("Ctrl+Z")
undoAction.triggered.connect(self.close_application)
aboutAction = QtGui.QAction("&About PTE...", self)
self.statusBar()
#Actual Main Menu with options
mainMenu = self.menuBar()
fileMenu = mainMenu.addMenu('&File')
fileMenu.addAction(quitAction)
fileMenu = mainMenu.addMenu('&Edit')
fileMenu.addAction(undoAction)
fileMenu = mainMenu.addMenu('&Help')
fileMenu.addAction(aboutAction)
self.home()
#Centering Window on the screen
def center(self):
gui = self.frameGeometry()
cp = QtGui.QDesktopWidget().availableGeometry().center()
gui.moveCenter(cp)
self.move(gui.topLeft())
def home(self):
#Buttons
qbtn = QtGui.QPushButton('Quit', self)
qbtn.clicked.connect(self.close_application)
rbtn = QtGui.QPushButton("Run", self)
rbtn.clicked.connect(self.close_application)
hbox = QtGui.QHBoxLayout()
hbox.addStretch(1)
hbox.addWidget(qbtn)
hbox.addWidget(rbtn)
vbox = QtGui.QVBoxLayout()
vbox.addStretch(1)
vbox.addLayout(hbox)
#self.show() #this only needs to be called once
#Labels and TextBox
Intervals = QtGui.QLabel('Number of intervals (0<=20) :')
Timesteps = QtGui.QLabel('Number of time steps (<=1000) : ')
IntervalsEdit = QtGui.QLineEdit()
TimestepsEdit = QtGui.QLineEdit()
grid = QtGui.QGridLayout()
grid.setSpacing(2)
grid.addWidget(Intervals, 1, 0)
grid.addWidget(IntervalsEdit, 1, 1)
grid.addWidget(Timesteps, 2, 0)
grid.addWidget(TimestepsEdit, 2, 1)
hbox.addLayout(grid) #this will add the grid to the horizontal layout.
#if you want it to be vertcally aligned change this to vbox.addLayout(grid)...
#... and this to self.setLayout(vbox)
self.setLayout(hbox)
self.show()
#What to display when the app is closed
def close_application(self):
#Popup message before closing the application in Binary
choice = QtGui.QMessageBox.question(self, 'Message',"Are you sure you want to exit?",
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No )
if choice == QtGui.QMessageBox.Yes:
print(" Until Next Time")
sys.exit()
else:
pass

Resources