I've created a class, which creates the GUI. I would like to add a menubar to it, but I don't really know, how should I add it to the window, if I work with a class. I can't make the menu bar appaer.
class Window(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
Main = QtGui.QMainWindow()
self.tab1 = QtGui.QWidget()
self.tab2 = QtGui.QWidget()
self.figure = plt.figure()
self.canvas = FigureCanvas(self.figure)
self.tempLabel=QtGui.QLabel("NC",self)
self.tempLabel.move(350,20)
self.tempLabel.setStyleSheet('color: black; font-size: 12pt;font: bold')
#menu bar
self.menu=QtGui.QMenu("Port", self)
self.menu.addAction('&ttyUSB0',)
self.menu.addAction('&ttyUSB1',)
self.menu.addAction('&ttyUSB2',)
self.layout = QtGui.QVBoxLayout()
self.layout.addWidget(self.canvas)
self.layout.addWidget(self.tempLabel)
self.tab1.setLayout(self.layout)
self.tabs = QtGui.QTabWidget()
self.tabs.addTab(self.tab1, "Database")
self.tabs.addTab(self.tab2, "Current")
self.tabs.show()
The menu bar is usually accessed from the main window, using the menuBar function.
I have edited your example code to show how to add menus, and also fixed a few other minor issues:
from PyQt4 import QtCore, QtGui
class Window(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
menubar = self.menuBar()
menu = menubar.addMenu('Port')
menu.addAction('&ttyUSB0')
menu.addAction('&ttyUSB1')
menu.addAction('&ttyUSB2')
self.tab1 = QtGui.QWidget()
self.tab2 = QtGui.QWidget()
self.figure = plt.figure()
self.canvas = FigureCanvas(self.figure)
self.tempLabel = QtGui.QLabel('NC', self)
self.tempLabel.move(350, 20)
self.tempLabel.setStyleSheet(
'color: black; font-size: 12pt;font: bold')
self.layout = QtGui.QVBoxLayout()
self.layout.addWidget(self.canvas)
self.layout.addWidget(self.tempLabel)
self.tab1.setLayout(self.layout)
self.tabs = QtGui.QTabWidget()
self.tabs.addTab(self.tab1, 'Database')
self.tabs.addTab(self.tab2, 'Current')
self.setCentralWidget(self.tabs)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
Related
I have build a small application using PyQt and as far as I know QStackedWidget is used for making multipage applications. The issue is that it is opening multiple pages and also I'm unable to redirect to class Xyz using button in class Abc.
main.py
from PyQt4 import QtGui, QtCore
import sys
class Window(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.stacked_widget = QtGui.QStackedWidget()
layout = QtGui.QVBoxLayout()
layout.setContentsMargins(0,0,0,0)
layout.addWidget(self.stacked_widget)
widget = QtGui.QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
widget_1 = Abc(self.stacked_widget)
widget_2 = Xyz(self.stacked_widget)
self.stacked_widget.addWidget(widget_1)
self.stacked_widget.addWidget(widget_2)
self.showMaximized()
class Abc(QtGui.QWidget):
def __init__(self, stacked_widget, parent=None):
super(Abc, self).__init__(parent)
self.stacked_widget = stacked_widget
self.frame = QtGui.QFrame()
self.frame_layout = QtGui.QVBoxLayout()
self.button = QtGui.QPushButton('Click me!')
self.button.clicked.connect(self.click)
self.frame_layout.addWidget(self.button)
self.frame.setLayout(self.frame_layout)
self.layout = QtGui.QVBoxLayout()
self.layout.addWidget(self.frame)
self.setLayout(self.layout)
self.showMaximized()
def click(self):
print("You clicked me!")
self.stacked_widget.setCurrentIndex(1)
class Xyz(QtGui.QWidget):
def __init__(self, parent=None):
super(Xyz, self).__init__(parent)
self.frame_layout = QtGui.QStackedLayout()
self.page1 = Page("Page 1", self.frame_layout)
self.page2 = Page("Page 2", self.frame_layout)
self.frame_layout.addWidget(self.page1)
self.frame_layout.addWidget(self.page2)
class Page(QtGui.QWidget):
def __init__(self, text, frame_layout, parent=None):
super(Page, self).__init__(parent)
print(self.width(), self.height())
self.frame_layout = frame_layout
self.frame = QtGui.QFrame()
self.frame_layout = QtGui.QVBoxLayout()
self.frame.setStyleSheet("background-color: rgb(191, 191, 191)")
self.label = QtGui.QLabel()
self.label.setText(text)
self.frame_layout.addWidget(self.label, alignment=QtCore.Qt.AlignCenter)
self.frame.setLayout(self.frame_layout)
self.layout = QtGui.QVBoxLayout()
self.layout.addWidget(self.frame)
self.layout.setContentsMargins(0,0,0,0)
self.setLayout(self.layout)
self.showMaximized()
print(self.width(), self.height())
if __name__ == "__main__":
app = QtGui.QApplication([])
window = Window()
window.show()
sys.exit(app.exec_())
The main problem is that you are not setting the QStackedLayout for the Xyz widget, the result is that all pages will actually appear as top level windows.
When a widget is added to a layout, it takes ownership of it; if the layout is already set to a widget, then the widget that was added to the layout becomes reparented to the other. The same happens if you set the layout afterwards.
Why does it show the first page as a separate window? And why doesn't it show the second?
When a new widget is created without a parent, it becomes a top level window; when a widget is added to a new stacked layout, Qt automatically tries to show it; you didn't set the layout to anything (which would reparent it as explained before), and the result is that the first page is shown as a standalone window.
Now, since the first "screen" is going to be shown only the first time, you can set that widget as the central widget, and then set a Xyz instance (which is actually a QStackedWidget subclass) as a new central widget.
Note that you don't need to use QWidget to add a QFrame if that's the only parent widget shown: you can just subclass QFrame.
This is a much simpler and cleaner version of your code:
from PyQt4 import QtGui, QtCore
class Window(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.startPage = Abc()
self.setCentralWidget(self.startPage)
self.startPage.startRequest.connect(self.buildPages)
def buildPages(self):
self.pages = Xyz()
self.setCentralWidget(self.pages)
class Abc(QtGui.QFrame):
startRequest = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(Abc, self).__init__(parent)
layout = QtGui.QVBoxLayout(self)
self.button = QtGui.QPushButton('Click me!')
self.button.clicked.connect(self.startRequest)
layout.addWidget(self.button)
class Xyz(QtGui.QStackedWidget):
def __init__(self, parent=None):
super(Xyz, self).__init__(parent)
self.page1 = Page("Page 1")
self.page2 = Page("Page 2")
self.addWidget(self.page1)
self.addWidget(self.page2)
self.page1.switchRequest.connect(lambda: self.setCurrentIndex(1))
self.page2.switchRequest.connect(lambda: self.setCurrentIndex(0))
class Page(QtGui.QFrame):
switchRequest = QtCore.pyqtSignal()
def __init__(self, text, parent=None):
super(Page, self).__init__(parent)
layout = QtGui.QVBoxLayout(self)
# set the background only for QFrame subclasses (which also includes
# QLabel), this prevents setting the background for other classes,
# such as the push button
self.setStyleSheet('''
QFrame {
background-color: rgb(191, 191, 191)
}
''')
# when adding a widget to a layout, the layout tries to automatically
# make it as big as possible (based on the widget's sizeHint); so you
# should not use the alignment argument for layout.addWidget(), but for
# the label instead
self.label = QtGui.QLabel(text, alignment=QtCore.Qt.AlignCenter)
layout.addWidget(self.label)
self.switchButton = QtGui.QPushButton('Switch')
layout.addWidget(self.switchButton)
self.switchButton.clicked.connect(self.switchRequest)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
I'm trying to add a scroll area to a QTabWideget.
At the moment I've set it up with two different tabs and the scrollArea is added to the second tab.
When I run my program, items are added to the scrollArea and the scroll bar is visible(policy set to always show), but it's greyed out.
Code:
class MyTableWidget(QWidget):
def __init__(self, parent):
super(QWidget, self).__init__(parent)
self.layout = QVBoxLayout(self)
# Initialize tab screen
self.tabs = QTabWidget()
self.tab1 = QWidget()
self.tab2 = QScrollArea()
self.tabs.setMaximumWidth(300)
self.tabs.setMaximumHeight(100)
# Add tabs
self.tabs.addTab(self.tab1,"Tab 1")
self.tabs.addTab(self.tab2,"Tab 2")
# Create first tab
# ...
# Create second tab
self.tab2.layout = QFormLayout(self)
self.tab2.setWidgetResizable(True)
self.tab2.setVerticalScrollBar(QScrollBar())
self.tab2.setVerticalScrollBarPolicy(2)
self.tab2.setFixedSize(100, 70)
self.t1 = QLabel('Test1', self)
self.t2 = QLabel('Test2', self)
self.t3 = QLabel('Test3', self)
self.t4 = QLabel('Test4', self)
self.t5 = QLabel('Test5', self)
self.t6 = QLabel('Test6', self)
self.tab2.layout.addRow(self.t1)
self.tab2.layout.addRow(self.t2)
self.tab2.layout.addRow(self.t3)
self.tab2.layout.addRow(self.t4)
self.tab2.layout.addRow(self.t5)
self.tab2.layout.addRow(self.t6)
self.tab2.setLayout(self.tab2.layout)
# Add tabs to widget
self.layout.addWidget(self.tabs)
self.setLayout(self.layout)
Code above turns out like this:
All squished together. I would like to be able to scroll and add more data without squishing whats there already.
Also, can I make the scroll area have the same background as seen in the picture below?
You do not have to replace the QScrollArea layout but add a new widget that has the QFormLayout as shown below.
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QApplication, \
QTabWidget, QScrollArea, QFormLayout, QLabel
class MyTableWidget(QWidget):
def __init__(self, parent=None):
super(QWidget, self).__init__(parent)
self.layout = QVBoxLayout(self)
self.tabs = QTabWidget()
self.tab1 = QWidget()
self.tab2 = QScrollArea()
self.tabs.addTab(self.tab1, 'Tab 1')
self.tabs.addTab(self.tab2, 'Tab 2')
content_widget = QWidget()
self.tab2.setWidget(content_widget)
flay = QFormLayout(content_widget)
self.tab2.setWidgetResizable(True)
self.t1 = QLabel('Test1')
self.t2 = QLabel('Test2')
self.t3 = QLabel('Test3')
self.t4 = QLabel('Test4')
self.t5 = QLabel('Test5')
self.t6 = QLabel('Test6')
flay.addRow(self.t1)
flay.addRow(self.t2)
flay.addRow(self.t3)
flay.addRow(self.t4)
flay.addRow(self.t5)
flay.addRow(self.t6)
self.layout.addWidget(self.tabs)
self.resize(300, 100)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
w = MyTableWidget()
w.show()
sys.exit(app.exec_())
I'm new to python and pyqt. I'm trying to open a new window after the first screen. My second window opens but without the options I specified, label and pushbutton.
from PyQt5 import QtWidgets
import sys
class secondwindow(QtWidgets.QMainWindow):
def __init__(self):
super(secondwindow, self).__init__()
self.label1 = QtWidgets.QLabel("Second Window");
self.button1 = QtWidgets.QPushButton("Click Me");
hbox = QtWidgets.QHBoxLayout()
hbox.addWidget(self.label1)
hbox.addWidget(self.button1)
self.setLayout(hbox)
class Window(QtWidgets.QWidget):
def btnclicked(self):
sender = self.sender()
if sender.text() == "OK":
self.secwin.show()
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.button1 = QtWidgets.QPushButton("OK");
vbox = QtWidgets.QVBoxLayout()
vbox.addWidget(self.button1)
self.setLayout(vbox)
self.button1.clicked.connect(self.btnclicked)
self.secwin = secondwindow()
self.show()
def main():
app = QtWidgets.QApplication(sys.argv)
main = Window()
main.show
sys.exit(app.exec())
if __name__ == '__main__':
main()
QMainWindow is a special widget because it has a defined structure, http://doc.qt.io/qt-5/qmainwindow.html#qt-main-window-framework:
As shown in the image there is already an area destined to place the widgets called Central Widget, in it you must place the widgets that you want to be displayed for it, you use setCentralWidget().
In your case the solution is:
class secondwindow(QtWidgets.QMainWindow):
def __init__(self):
super(secondwindow, self).__init__()
central_widget = QtWidgets.QWidget()
self.label1 = QtWidgets.QLabel("Second Window")
self.button1 = QtWidgets.QPushButton("Click Me")
hbox = QtWidgets.QHBoxLayout(central_widget)
hbox.addWidget(self.label1)
hbox.addWidget(self.button1)
self.setCentralWidget(central_widget)
I have my qtablewidget defined like this:
def __init__(self, parent = None):
super(Window, self).__init__(parent)
QtGui.QWidget.__init__(self)
QtGui.QTableWidget.setMinimumSize(self, 500, 500)
QtGui.QTableWidget.setWindowTitle(self, "Custom table widget")
self.table = QtGui.QTableWidget()
rowf = 3
self.table.setColumnCount(3)
self.table.setRowCount(rowf)
self.table.setHorizontalHeaderItem(0, QtGui.QTableWidgetItem("col1"))
self.table.setHorizontalHeaderItem(1, QtGui.QTableWidgetItem("col2"))
self.table.setHorizontalHeaderItem(2, QtGui.QTableWidgetItem("col3"))
self.table.verticalHeader().hide()
header = self.table.horizontalHeader()
header.setResizeMode(0, QtGui.QHeaderView.ResizeToContents)
header.setResizeMode(1, QtGui.QHeaderView.ResizeToContents)
header.setResizeMode(2, QtGui.QHeaderView.ResizeToContents)
self.buttonBox = QtGui.QDialogButtonBox(self)
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Ok)
self.verticalLayout = QtGui.QVBoxLayout(self)
self.verticalLayout.addWidget(self.table)
self.verticalLayout.addWidget(self.buttonBox)
self.buttonBox.accepted.connect(self.close)
self.buttonBox.rejected.connect(self.close)
I would like my end result to look something similar to the pic below but right now, the layout that I'm trying to add doesn't quiet work the way I'd like it to. I'm a beginner at pyqt. I've tried this layout before on a qlistview and it worked well.
add {your table}.table.horizontalHeader().setStretchLastSection(True) and/or {your table}.verticalHeader().setStretchLastSection(True)
import sys
from PyQt4 import QtGui
from PyQt4 import QtCore
class Window(QtGui.QWidget):
def __init__(self, parent=None):
super(Window, self).__init__(parent=parent)
QtGui.QTableWidget.setMinimumSize(self, 500, 500)
QtGui.QTableWidget.setWindowTitle(self, "Custom table widget")
self.table = QtGui.QTableWidget()
rowf = 3
self.table.setColumnCount(3)
self.table.setRowCount(rowf)
self.table.setHorizontalHeaderItem(0, QtGui.QTableWidgetItem("col1"))
self.table.setHorizontalHeaderItem(1, QtGui.QTableWidgetItem("col2"))
self.table.setHorizontalHeaderItem(2, QtGui.QTableWidgetItem("col3"))
self.table.horizontalHeader().setStretchLastSection(True)
# self.table.verticalHeader().setStretchLastSection(True)
self.buttonBox = QtGui.QDialogButtonBox(self)
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Ok)
self.verticalLayout = QtGui.QVBoxLayout(self)
self.verticalLayout.addWidget(self.table)
self.verticalLayout.addWidget(self.buttonBox)
self.buttonBox.accepted.connect(self.close)
self.buttonBox.rejected.connect(self.close)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec_())
Only Horizontal:
Only Vertical:
Vertical and Horizontal:
I have written the code below:
import sys
from PyQt4 import QtCore, QtGui
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.central_widget = QtGui.QStackedWidget()
self.setCentralWidget(self.central_widget)
Login_Widget = LoginPage(self)
self.central_widget.addWidget(Login_Widget)
self.central_widget.setCurrentWidget(Login_Widget)
self.setStyleSheet("background-color:#FFDA00;")
class LoginPage(QtGui.QWidget):
def __init__(self, parent=None):
super(LoginPage, self).__init__(parent)
self.Username = QtGui.QLineEdit(self)
self.Password = QtGui.QLineEdit(self)
self.Password.setEchoMode(QtGui.QLineEdit.Password)
self.buttonLogin = QtGui.QPushButton('Login', self)
self.cancelButton = QtGui.QPushButton('Cancel', self)
loginLayout = QtGui.QFormLayout()
loginLayout.addRow("Username", self.Username)
loginLayout.addRow("Password", self.Password)
horizontallayout = QtGui.QHBoxLayout()
horizontallayout.addWidget(self.buttonLogin)
horizontallayout.addWidget(self.cancelButton)
layout = QtGui.QVBoxLayout(self)
layout.addLayout(loginLayout)
layout.addLayout(horizontallayout)
self.setLayout(layout)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
With the code above, When I run the code, it sets everything orange. I wanted to set the background orange, the lineedit white and the buttons silvery-grey. How would I set different colors for individual widget items?? Also is there any way that I could set a colour for the Window bar (the bar containing the window-title, exit button, minimize button, and re-size button)
Any help will be much appreciated!
You can set different style properties for individual widgets.
Have a look at this link Qt Style Sheets Examples as it cover how to set different style properties for most of the widgets.
You can also save the stylesheeet as .qss file and save it externally.
css = '''
QMainWindow
{
background:orange;
}
QLineEdit
{
background:white;
}
QPushButton
{
background:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #FAFFFA, stop: 0.4 #F5F7F5,
stop: 0.5 #F0F2F0, stop: 1.0 #EDEDED);
}
'''
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.central_widget = QtGui.QStackedWidget()
self.setCentralWidget(self.central_widget)
Login_Widget = LoginPage(self)
self.central_widget.addWidget(Login_Widget)
self.central_widget.setCurrentWidget(Login_Widget)
class LoginPage(QtGui.QWidget):
def __init__(self, parent=None):
super(LoginPage, self).__init__(parent)
self.Username = QtGui.QLineEdit(self)
self.Password = QtGui.QLineEdit(self)
self.Password.setEchoMode(QtGui.QLineEdit.Password)
self.buttonLogin = QtGui.QPushButton('Login', self)
self.cancelButton = QtGui.QPushButton('Cancel', self)
loginLayout = QtGui.QFormLayout()
loginLayout.addRow("Username", self.Username)
loginLayout.addRow("Password", self.Password)
horizontallayout = QtGui.QHBoxLayout()
horizontallayout.addWidget(self.buttonLogin)
horizontallayout.addWidget(self.cancelButton)
layout = QtGui.QVBoxLayout(self)
layout.addLayout(loginLayout)
layout.addLayout(horizontallayout)
self.setLayout(layout)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
app.setStyleSheet(css)#<------------set your stylesheet
window = MainWindow()
window.show()
app.exec_()
As for the window title bar, it is not possible to set color or any properties. Your best bet is to hide it and implement your own window title bar.