How do I remove QLabels created iteratively? - python

I'm making an app where I'm iteratively creating QLabel. I'm trying to remove them with another button.
I want to remove the 'history'. I have tried different things like label.remove() and so on, but it would add no value to add my previous attempts here (also my attempts weren't on this reproducible example).
Here's the code that I have:
from PyQt5.QtWidgets import *
import sys
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.left = 10
self.top = 10
self.width = 400
self.height = 75
self.initUI()
self.layout = QVBoxLayout()
self.line = QLineEdit()
label = QLabel('Enter a WORD:')
run_button = QPushButton('Run')
reset_button = QPushButton('Reset History')
self.layout.addWidget(label)
self.layout.addWidget(self.line)
self.layout.addWidget(run_button)
self.layout.addWidget(reset_button)
widget = QWidget()
widget.setLayout(self.layout)
run_button.clicked.connect(self.on_click)
self.setCentralWidget(widget)
def initUI(self):
self.setGeometry(self.left, self.top, self.width, self.height)
def on_click(self):
response = QLabel(self.line.text())
self.layout.addWidget(response)
self.line.selectAll()
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()

You have to store the QLabels to later remove them from the layout and delete them, and then additionally recalculate the size of the window:
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.left = 10
self.top = 10
self.width = 400
self.height = 75
self.initUI()
self.layout = QVBoxLayout()
self.line = QLineEdit()
label = QLabel("Enter a WORD:")
run_button = QPushButton("Run")
reset_button = QPushButton("Reset History")
self.layout.addWidget(label)
self.layout.addWidget(self.line)
self.layout.addWidget(run_button)
self.layout.addWidget(reset_button)
widget = QWidget()
widget.setLayout(self.layout)
run_button.clicked.connect(self.add_history)
reset_button.clicked.connect(self.delete_history)
self.setCentralWidget(widget)
self._history_labels = []
def initUI(self):
self.setGeometry(self.left, self.top, self.width, self.height)
def add_history(self):
history = QLabel(self.line.text())
self.layout.addWidget(history)
self.line.selectAll()
self._history_labels.append(history)
def delete_history(self):
for history in self._history_labels:
self.layout.removeWidget(history)
history.deleteLater()
self._history_labels = []
width = self.size().width()
self.adjustSize()
height = self.sizeHint().height()
QTimer.singleShot(0, lambda: self.resize(width, height))

To me, it would be easier to use one label to store all of your responses. Every time you hit "Run" button, append a new line to your label. Changed lines highlighted with # <---
from PyQt5.QtWidgets import *
import sys
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.left = 10
self.top = 10
self.width = 400
self.height = 75
self.initUI()
self.layout = QVBoxLayout()
self.line = QLineEdit()
label = QLabel('Enter a WORD:')
run_button = QPushButton('Run')
reset_button = QPushButton('Reset History')
self.label = QLabel() # <-----
self.layout.addWidget(label)
self.layout.addWidget(self.line)
self.layout.addWidget(run_button)
self.layout.addWidget(reset_button)
self.layout.addWidget(self.label) # <-----
widget = QWidget()
widget.setLayout(self.layout)
run_button.clicked.connect(self.on_click)
reset_button.clicked.connect(self.reset_click) # <-----
self.setCentralWidget(widget)
def initUI(self):
self.setGeometry(self.left, self.top, self.width, self.height)
def on_click(self):
self.label.setText(self.label.text() + '\n' + self.line.text()) # <-----
self.line.selectAll()
def reset_click(self): # <-----
self.label.setText('') # <-----
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
self.layout = QVBoxLayout()
self.line = QLineEdit()
label = QLabel('Enter a WORD:')
run_button = QPushButton('Run')
reset_button = QPushButton('Reset History')
self.label = QLabel() # <-----
self.layout.addWidget(label)
self.layout.addWidget(self.line)
self.layout.addWidget(run_button)
self.layout.addWidget(reset_button)
self.layout.addWidget(self.label) # <-----
widget = QWidget()
widget.setLayout(self.layout)
run_button.clicked.connect(self.on_click)
reset_button.clicked.connect(self.reset_click) # <-----
self.setCentralWidget(widget)
def initUI(self):
self.setGeometry(self.left, self.top, self.width, self.height)
def on_click(self):
self.label.setText(self.label.text() + '\n' + self.line.text()) # <-----
self.line.selectAll()
def reset_click(self): # <-----
self.label.setText('') # <-----
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()

Related

How can I maintain the ability to type after using QLineEdit.selectAll?

I want users of my app to be able to press the button, and then keep typing. With QLineEdit.selectAll(), I am able to select the text entered after Run is pressed, but typing won't do anything. See:
The text is selected due to QLineEdit.selectAll(), but typing won't do anything.
Here's what I have so far:
from PyQt5.QtWidgets import *
import sys
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.title = 'window title'
self.left = 10
self.top = 10
self.width = 400
self.height = 75
self.initUI()
self.layout = QVBoxLayout()
self.line = QLineEdit()
label = QLabel('Enter a WORD:')
run_button = QPushButton('Run')
self.layout.addWidget(label)
self.layout.addWidget(self.line)
self.layout.addWidget(run_button)
widget = QWidget()
widget.setLayout(self.layout)
run_button.clicked.connect(self.on_click)
self.setCentralWidget(widget)
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
def on_click(self):
response = QLabel(self.line.text())
self.layout.addWidget(response)
self.line.selectAll()
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
selectAll() is tricky. It looks like the widget has the focus, but it doesn't. Use setFocus(). Order doesn't matter in this case
self.line.setFocus()
self.line.selectAll()
or
self.line.selectAll()
self.line.setFocus()
Further, in this UI, you can hook up the returnPressed signal of self.line to on_click so that when the user presses enter/return in self.line, the on_click method runs.
self.line.returnPressed.connect(self.on_click)
Putting it all together:
from PyQt5.QtWidgets import *
import sys
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.left = 10
self.top = 10
self.width = 400
self.height = 75
self.initUI()
self.layout = QVBoxLayout()
self.line = QLineEdit()
label = QLabel('Enter a WORD:')
run_button = QPushButton('Run')
reset_button = QPushButton('Reset History')
self.label = QLabel()
self.layout.addWidget(label)
self.layout.addWidget(self.line)
self.layout.addWidget(run_button)
self.layout.addWidget(reset_button)
self.layout.addWidget(self.label)
widget = QWidget()
widget.setLayout(self.layout)
run_button.clicked.connect(self.on_click)
self.line.returnPressed.connect(self.on_click)
reset_button.clicked.connect(self.reset_click)
self.setCentralWidget(widget)
def initUI(self):
self.setGeometry(self.left, self.top, self.width, self.height)
def on_click(self):
self.label.setText(self.label.text() + '\n' + self.line.text())
self.line.setFocus()
self.line.selectAll()
def reset_click(self):
self.label.setText('')
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
By using this:
self.line.selectAll()
self.line.grabKeyboard()
It will select the text entered at every push of the button, and you will be able to continue typing without clicking in the textbox.

Python How to display in 1 window instead of 2

Im a green in python, and i can't display my gui in 1 window, but it displays 2. How can I display the data in 1 window? I know the quality of the question isn't perfect but i can't seem to know how to do it. How can i put these stuff in one window? Any help would be appreciated.
from PyQt5.QtWidgets import QMainWindow, QApplication, QFileSystemModel, QTreeView, QWidget, QVBoxLayout
from PyQt5.QtGui import QIcon
class App(QWidget):
def __init__(self):
super().__init__()
self.title = 'PyQt5 file system view - pythonspot.com'
self.left = 10
self.top = 10
self.width = 640
self.height = 480
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.model = QFileSystemModel()
self.model.setRootPath('')
self.tree = QTreeView()
self.tree.setModel(self.model)
self.tree.setAnimated(False)
self.tree.setIndentation(20)
self.tree.setSortingEnabled(True)
self.tree.setWindowTitle("Dir View")
self.tree.resize(640, 480)
windowLayout = QVBoxLayout()
windowLayout.addWidget(self.tree)
self.setLayout(windowLayout)
self.show()
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 500, 520)
self.setWindowTitle('Total Commander')
self.setWindowIcon(QIcon('tcmd.ico'))
self.statusBar()
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu = menubar.addMenu('&Mark')
fileMenu = menubar.addMenu('&Commands')
fileMenu = menubar.addMenu('&Net')
fileMenu = menubar.addMenu('&Show')
fileMenu = menubar.addMenu('&Configuration')
fileMenu = menubar.addMenu('&Start')
# fileMenu = menubar.addMenu('& ')
fileMenu = menubar.addMenu('&Help')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ap = App()
ex = Example()
sys.exit(app.exec_())
Hello, Im a green in python, and i can't display my gui in 1 window, but it displays 2. How can I display the data in 1 window? I know the quality of the question isn't perfect but i can't seem to know how to do it. How can i put these stuff in one window? Any help would be appreciated.
Try it:
import sys
from PyQt5.QtWidgets import (QMainWindow, QApplication, QFileSystemModel,
QTreeView, QWidget, QVBoxLayout)
from PyQt5.QtGui import QIcon
class App(QWidget):
def __init__(self):
super().__init__()
self.title = 'PyQt5 file system view - pythonspot.com'
self.left = 10
self.top = 10
self.width = 640
self.height = 480
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.model = QFileSystemModel()
self.model.setRootPath('')
self.tree = QTreeView()
self.tree.setModel(self.model)
self.tree.setAnimated(False)
self.tree.setIndentation(20)
self.tree.setSortingEnabled(True)
self.tree.setWindowTitle("Dir View")
self.tree.resize(640, 480)
windowLayout = QVBoxLayout()
windowLayout.addWidget(self.tree)
self.setLayout(windowLayout)
# self.show()
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
# + vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget) # Sets the given widget to be the main window's central widget.
self.ap = App()
layout = QVBoxLayout(self.centralWidget)
layout.addWidget(self.ap)
# + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
def initUI(self):
self.setGeometry(300, 300, 500, 520)
self.setWindowTitle('Total Commander')
self.setWindowIcon(QIcon('tcmd.ico'))
self.statusBar()
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu = menubar.addMenu('&Mark')
fileMenu = menubar.addMenu('&Commands')
fileMenu = menubar.addMenu('&Net')
fileMenu = menubar.addMenu('&Show')
fileMenu = menubar.addMenu('&Configuration')
fileMenu = menubar.addMenu('&Start')
# fileMenu = menubar.addMenu('& ')
fileMenu = menubar.addMenu('&Help')
# self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
# ap = App()
ex = Example()
ex.show() # +
sys.exit(app.exec_())

How to open new window with push button [duplicate]

This question already has an answer here:
How to open a window with a click of a button from another window using PyQt?
(1 answer)
Closed 3 years ago.
How do I open a new window which allows me to select the time from the following code? I tried to use connect function to connect to windows2 however it appears that there is an error.
I would like to select time by a dropbox where I could choose time by 10 am, 11 am, ect.. Does anyone know how you could implement this as well?
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.label = QLabel()
self.calendar = QCalendarWidget()
self.title="Select date from calendar"
self.left = 600
self.top = 300
self.width = 500
self.height = 480
self.iconName = "home.png"
self.setWindowTitle(self.title)
self.setWindowIcon(QtGui.QIcon(self.iconName))
self.setGeometry(self.left, self.top, self.width, self.height)
self.proceedbutton = QPushButton("Proceed to select time", self)
self.proceedbutton.setGeometry(290, 430, 190, 40)
self.proceedbutton.setToolTip("<h3>Start the Session</h3>")
self.proceedbutton.clicked.connect(self.window2)
self.hide()
self.backbutton = QPushButton("Back", self)
self.backbutton.setGeometry(200, 430, 80, 40)
self.backbutton.setToolTip("<h3>Start the Session</h3>")
self.Calendar()
self.show()
def Calendar(self):
CalendarVbox = QVBoxLayout()
self.calendar.setGridVisible(True)
self.label.setFont(QtGui.QFont("Sanserif", 10))
self.label.setStyleSheet('color:black')
CalendarVbox.addWidget(self.calendar)
CalendarVbox.addWidget(self.label)
self.setLayout(CalendarVbox)
self.calendar.selectionChanged.connect(self.onSelectionChanged)
def window2(self):
self.label = QLabel("Select Time", self)
self.label.move(200,430)
self.setWindowTitle("Select Time")
self.setGeometry(self.left, self.top, self.width, self.height)
self.show()
def onSelectionChanged(self):
ca = self.calendar.selectedDate()
self.label.setText(ca.toString())
App = QApplication(sys.argv)
window = Window()
sys.exit(App.exec())
Start using layouts!
A widget without a parent - there is a window.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class Window(QWidget): #(QMainWindow):
def __init__(self):
super().__init__()
self.title="Select date from calendar"
self.left, self.top, self.width, self.height = 600, 100, 500, 480
self.iconName = "Ok.png" # <--- home.png
self.setWindowTitle(self.title)
self.setWindowIcon(QtGui.QIcon(self.iconName))
self.setGeometry(self.left, self.top, self.width, self.height)
self.calendar = QCalendarWidget()
self.calendar.setGridVisible(True)
self.calendar.selectionChanged.connect(self.onSelectionChanged)
self.label = QLabel()
self.label.setFont(QtGui.QFont("Sanserif", 10))
self.label.setStyleSheet('color: blue;')
self.proceedbutton = QPushButton("Proceed to select time", self)
self.proceedbutton.setToolTip("<h3>Start the Session</h3>")
self.proceedbutton.clicked.connect(self.window2)
self.backbutton = QPushButton("Back", self)
self.backbutton.setToolTip("<h3>Start the Session</h3>")
self.comboBox = None
self.grid = QtWidgets.QGridLayout(self)
self.grid.addWidget(self.calendar, 0, 0, 1, 3)
self.grid.addWidget(self.label, 1, 0, 1, 3)
self.grid.addWidget(self.backbutton, 2, 1, 1, 1)
self.grid.addWidget(self.proceedbutton, 2, 2, 1, 1)
def window2(self):
self.window = QWidget()
self.window.setWindowTitle("Select Time")
self.window.setGeometry(self.left/3, self.top, self.width/3, self.height/3)
self.label = QLabel("Select Time") # --- , self)
self.comboBox = QtWidgets.QComboBox()
self.comboBox.addItems(["choose time", "10", "11", "12"])
self.comboBox.activated[str].connect(self.onComboActivated)
layout = QFormLayout(self.window)
layout.addRow('Choose Time', self.comboBox)
self.window.show()
def onSelectionChanged(self):
ca = self.calendar.selectedDate()
self.label.setText(ca.toString())
def onComboActivated(self, text):
print("choose time: {}".format(text))
if __name__ == '__main__':
App = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(App.exec())

Control window and Display window

I need two PyQt windows to run in the same time on a multiple display machine: one screen for display and the other for input.
In the following example i'm trying to have a simple window with a button and another window with a label. When i push the button, the other windows label text should change:
import sys
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QApplication, QWidget, QDialog, QInputDialog,QDesktopWidget,QVBoxLayout,QPushButton,QMainWindow,QAction,QFileDialog,QGroupBox,QGridLayout,QLabel
class Control_Pannel(QWidget):
def __init__(self):
super().__init__()
self.title = 'Main Control Pannel'
self.left = 10
self.top = 10
self.width = 640
self.height = 400
self.text = "Display text"
self.InitializeUI()
def InitializeUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left,self.top,self.width,self.height)
self.inputBox = QGroupBox("Display")
layout = QGridLayout()
layout.setColumnStretch(1, 4)
layout.setColumnStretch(2, 4)
button = QPushButton('Push here to change text')
layout.addWidget(button,0,0)
button.clicked.connect(self.on_click)
self.inputBox.setLayout(layout)
windowLayout = QVBoxLayout()
windowLayout.addWidget(self.inputBox)
self.setLayout(windowLayout)
self.show()
app = QApplication(sys.argv)
ex=InputWindows()
sys.exit(app.exec_())
#pyqtSlot()
def on_click(self):
InputWindows.text = "Modified text after button push"
print(InputWindows.text)
InputWindows.update()
##???? here i don't know how to make the changes be reflected in the other window, even if when i print the .text attribute it seems to have changed.
class InputWindows(QDialog):
def __init__(self):
super().__init__()
self.title = 'Display Pannel'
self.left = 5
self.top = 5
self.width = 300
self.height = 300
self.text = "Original Text"
self.InitializeUI()
def InitializeUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left,self.top,self.width,self.height)
self.createDisplayGridLayout()
windowLayout = QVBoxLayout()
windowLayout.addWidget(self.horizontalGroupBox)
self.setLayout(windowLayout)
self.show()
def createDisplayGridLayout(self):
self.horizontalGroupBox = QGroupBox("Grid")
layout = QGridLayout()
layout.setColumnStretch(1, 4)
layout.setColumnStretch(2, 4)
self.label = QLabel(self.text)
layout.addWidget(self.label,0,0)
if __name__=='__main__':
app=QApplication(sys.argv)
ex=Control_Pannel()
sys.exit(app.exec_())
With InputWindows.update() i'm getting that first argument of unbound method must have a type QWidget and if i try InputWindows.label.update() i'm getting type object inputwindows has no attribute label
InputWindows is a class, it is an abstraction so you generally have to create an object, I ask you: if you have n Windows InputWindows, to which window would you update the text ?, we would not know, so by simple logic we see that it is wrong to do it. On the other hand, consider each class as a black box where it is stimulated by inputs, and outputs are obtained, in your case Control_Pannel must have an output: the new text, but that output is asynchronous since it changes and must be used when changing , and that in Qt is a signal, so we must create it. On the other hand, InputWindows must receive the information to create a slot that updates the text in the QLabel as shown below:
import sys
from PyQt5 import QtCore, QtWidgets
class Control_Pannel(QtWidgets.QWidget):
sendSignal = QtCore.pyqtSignal(str)
def __init__(self):
super().__init__()
self.title = 'Main Control Pannel'
self.left = 10
self.top = 10
self.width = 640
self.height = 400
self.text = "Display text"
self.InitializeUI()
def InitializeUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left,self.top,self.width,self.height)
self.inputBox = QtWidgets.QGroupBox("Display")
layout = QtWidgets.QGridLayout()
layout.setColumnStretch(1, 4)
layout.setColumnStretch(2, 4)
button = QtWidgets.QPushButton('Push here to change text')
layout.addWidget(button,0,0)
button.clicked.connect(self.on_click)
self.inputBox.setLayout(layout)
windowLayout = QtWidgets.QVBoxLayout(self)
windowLayout.addWidget(self.inputBox)
#QtCore.pyqtSlot()
def on_click(self):
text = "Modified text after button push"
self.sendSignal.emit(text)
class InputWindows(QtWidgets.QDialog):
def __init__(self):
super().__init__()
self.title = 'Display Pannel'
self.left = 5
self.top = 5
self.width = 300
self.height = 300
self.InitializeUI()
self.setText("Original Text")
#QtCore.pyqtSlot(str)
def setText(self, text):
self.label.setText(text)
def InitializeUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left,self.top,self.width,self.height)
self.createDisplayGridLayout()
windowLayout = QtWidgets.QVBoxLayout(self)
windowLayout.addWidget(self.horizontalGroupBox)
self.setLayout(windowLayout)
def createDisplayGridLayout(self):
self.horizontalGroupBox = QtWidgets.QGroupBox("Grid")
layout = QtWidgets.QGridLayout()
layout.setColumnStretch(1, 4)
layout.setColumnStretch(2, 4)
self.label = QtWidgets.QLabel()
layout.addWidget(self.label, 0, 0)
self.horizontalGroupBox.setLayout(layout)
if __name__=='__main__':
app = QtWidgets.QApplication(sys.argv)
ex1 = Control_Pannel()
ex1.show()
ex2 = InputWindows()
ex2.show()
ex1.sendSignal.connect(ex2.setText)
sys.exit(app.exec_())

How to add PyQt5 QtWidgets.QTabWidget() properly to sub-classed QWidget

I am attempting to subclass PyQt5 QWidget and encapsulate a QTabWidget() for dynamic reuse and have run into an issue where either the Tabs do not show or they do show but their content does not show.
I think I must be missing something fundamental and am fairly new to Qt.
Here is example code where I cannot get things to show properly.
import sys
import os
from PyQt5 import QtCore, QtGui, QtWidgets
scriptDir = os.path.dirname(os.path.realpath(__file__))
testImage = scriptDir + os.path.sep + 'test_tree.png'
class TabImages(QtWidgets.QWidget):
def __init__(self, parent):
super(QtWidgets.QWidget, self).__init__(parent)
self.container = QtWidgets.QVBoxLayout()
# Initialize tab screen
self.tabs = QtWidgets.QTabWidget()
self.tab1 = QtWidgets.QWidget()
self.tab2 = QtWidgets.QWidget()
self.tab3 = QtWidgets.QWidget()
self.tab1_layout = QtWidgets.QVBoxLayout()
self.tab2_layout = QtWidgets.QVBoxLayout()
self.tab3_layout = QtWidgets.QVBoxLayout()
self.tab1.setLayout(self.tab1_layout)
self.tab2.setLayout(self.tab2_layout)
self.tab3.setLayout(self.tab3_layout)
self.tab1_label = QtWidgets.QLabel()
self.tab2_label = QtWidgets.QLabel()
self.tab3_label = QtWidgets.QLabel()
self.tab1_pixMap = QtGui.QPixmap(scriptDir + os.path.sep + 'test_image1.png')
self.tab2_pixMap = QtGui.QPixmap(scriptDir + os.path.sep + 'test_image2.png')
self.tab3_pixMap = QtGui.QPixmap(scriptDir + os.path.sep + 'test_image3.png')
self.tab1_label.setPixmap(self.tab1_pixMap)
self.tab2_label.setPixmap(self.tab2_pixMap)
self.tab3_label.setPixmap(self.tab3_pixMap)
self.tab1_layout.addWidget(self.tab1_label)
self.tab2_layout.addWidget(self.tab2_label)
self.tab3_layout.addWidget(self.tab3_label)
# Add tabs
self.tabs.addTab(self.tab1,"Tab 1")
self.tabs.addTab(self.tab2,"Tab 2")
self.tabs.addTab(self.tab3,"Tab 3")
self.container.addWidget(self.tabs)
#self.tabs.show()
class Main(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.title = 'Tabbed PixMap'
self.left = 0
self.top = 0
self.width = 800
self.height = 600
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.tabImages = TabImages(self)
self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.tabImages)
#self.layout.addLayout(self.tabImages.container)
self.center()
self.show()
def center(self):
frameGm = self.frameGeometry()
screen = QtWidgets.QApplication.desktop().screenNumber(QtWidgets.QApplication.desktop().cursor().pos())
centerPoint = QtWidgets.QApplication.desktop().screenGeometry(screen).center()
frameGm.moveCenter(centerPoint)
self.move(frameGm.topLeft())
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
main = Main()
sys.exit(app.exec_())
Note the commented out
tabs.show()
if I un-comment this the tab container shows but outside the main window.
I have also tried adding both the layout and widget but neither seem to change the behavior. I would appreciate anyone's insight.
If I were doing this same thing in a single window without trying to subclass as a new widget then I do it like this and use setCentralWidget() and it works fine
import sys
import os
from PyQt5 import QtCore, QtGui, QtWidgets
scriptDir = os.path.dirname(os.path.realpath(__file__))
testImage = scriptDir + os.path.sep + 'test_tree.png'
class Main(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.title = 'Tabbed PixMap'
self.left = 0
self.top = 0
self.width = 800
self.height = 600
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
# Initialize tab screen
self.tabs = QtWidgets.QTabWidget()
self.tab1 = QtWidgets.QWidget()
self.tab2 = QtWidgets.QWidget()
self.tab3 = QtWidgets.QWidget()
self.tab1_layout = QtWidgets.QVBoxLayout()
self.tab2_layout = QtWidgets.QVBoxLayout()
self.tab3_layout = QtWidgets.QVBoxLayout()
self.tab1.setLayout(self.tab1_layout)
self.tab2.setLayout(self.tab2_layout)
self.tab3.setLayout(self.tab3_layout)
self.tab1_label = QtWidgets.QLabel()
self.tab2_label = QtWidgets.QLabel()
self.tab3_label = QtWidgets.QLabel()
self.tab1_pixMap = QtGui.QPixmap(scriptDir + os.path.sep + 'test_image1.png')
self.tab2_pixMap = QtGui.QPixmap(scriptDir + os.path.sep + 'test_image2.png')
self.tab3_pixMap = QtGui.QPixmap(scriptDir + os.path.sep + 'test_image3.png')
self.tab1_label.setPixmap(self.tab1_pixMap)
self.tab2_label.setPixmap(self.tab2_pixMap)
self.tab3_label.setPixmap(self.tab3_pixMap)
self.tab1_layout.addWidget(self.tab1_label)
self.tab2_layout.addWidget(self.tab2_label)
self.tab3_layout.addWidget(self.tab3_label)
# Add tabs
self.tabs.addTab(self.tab1,"Tab 1")
self.tabs.addTab(self.tab2,"Tab 2")
self.tabs.addTab(self.tab3,"Tab 3")
self.setCentralWidget(self.tabs)
self.center()
self.show()
def center(self):
frameGm = self.frameGeometry()
screen = QtWidgets.QApplication.desktop().screenNumber(QtWidgets.QApplication.desktop().cursor().pos())
centerPoint = QtWidgets.QApplication.desktop().screenGeometry(screen).center()
frameGm.moveCenter(centerPoint)
self.move(frameGm.topLeft())
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
main = Main()
sys.exit(app.exec_())
I do not know that it makes a difference but I am running the recompiled version of PyQT5 packaged with Anaconda on a windows 10 machine.
Thanks
Your main problem arises because:
One of the reasons why in the first image the window is outside the window is because the self.container has never been assigned.
The same happens with self.layout.
A layout is not a widget, it is not a graphic element, it is just a class that manages the position and size of the widgets that are assigned to the widget that is assigned the same layout, so if you do not assign a layout to a specific widget this will not work.
In the case of self.layout I see that it is unnecessary since you only have one widget: self.tabImages and this can be the centralwidget, if you had more widgets you could create a new centralwidget, assign it a layout to that new central widget, and in that layout add the other widgets.
import sys
import os
from PyQt5 import QtCore, QtGui, QtWidgets
scriptDir = os.path.dirname(os.path.realpath(__file__))
testImage = os.path.join(scriptDir, 'test_tree.png')
class TabImages(QtWidgets.QWidget):
def __init__(self, parent=None):
super(QtWidgets.QWidget, self).__init__(parent)
self.container = QtWidgets.QVBoxLayout(self)
# Initialize tab screen
self.tabs = QtWidgets.QTabWidget()
self.tab1 = QtWidgets.QWidget()
self.tab2 = QtWidgets.QWidget()
self.tab3 = QtWidgets.QWidget()
self.tab1_layout = QtWidgets.QVBoxLayout()
self.tab2_layout = QtWidgets.QVBoxLayout()
self.tab3_layout = QtWidgets.QVBoxLayout()
self.tab1.setLayout(self.tab1_layout)
self.tab2.setLayout(self.tab2_layout)
self.tab3.setLayout(self.tab3_layout)
self.tab1_label = QtWidgets.QLabel()
self.tab2_label = QtWidgets.QLabel()
self.tab3_label = QtWidgets.QLabel()
self.tab1_pixMap = QtGui.QPixmap(os.path.join(scriptDir, 'test_image1.png'))
self.tab2_pixMap = QtGui.QPixmap(os.path.join(scriptDir, 'test_image2.png'))
self.tab3_pixMap = QtGui.QPixmap(os.path.join(scriptDir,'test_image3.png'))
self.tab1_label.setPixmap(self.tab1_pixMap)
self.tab2_label.setPixmap(self.tab2_pixMap)
self.tab3_label.setPixmap(self.tab3_pixMap)
self.tab1_layout.addWidget(self.tab1_label)
self.tab2_layout.addWidget(self.tab2_label)
self.tab3_layout.addWidget(self.tab3_label)
# Add tabs
self.tabs.addTab(self.tab1,"Tab 1")
self.tabs.addTab(self.tab2,"Tab 2")
self.tabs.addTab(self.tab3,"Tab 3")
self.container.addWidget(self.tabs)
class Main(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.title = 'Tabbed PixMap'
self.left = 0
self.top = 0
self.width = 800
self.height = 600
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.tabImages = TabImages()
self.setCentralWidget(self.tabImages)
self.center()
self.show()
def center(self):
frameGm = self.frameGeometry()
screen = QtWidgets.QApplication.desktop().screenNumber(QtWidgets.QApplication.desktop().cursor().pos())
centerPoint = QtWidgets.QApplication.desktop().screenGeometry(screen).center()
frameGm.moveCenter(centerPoint)
self.move(frameGm.topLeft())
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
main = Main()
sys.exit(app.exec_())

Categories