I am making Multi-Page application in PyQt4, so whenever user does specific action (clicking a button for example) there is an update in widgets.
For example, There are 5 widgets and one button:
3 widgets are hidden, 2 widgets are shown.
Whenever i click the button, it will hide 2 widgets, and show those 3.
So in code, it should be something like this:
# startup
def somefunc(self):
widget1 = QtGui.QLabel("Widget1", self)
widget2 = QtGui.QLabel("Widget2", self)
widget3 = QtGui.QLabel("Widget3", self)
widget4 = QtGui.QLabel("Widget4", self)
widget5 = QtGui.QLabel("Widget5", self)
widget1.setHidden()
widget2.setHidden()
widget3.setHidden()
widget4.show()
widget5.show()
btn = QtGui.QPushButton("Click", self)
btn.clicked.connect(self.SomeotherFunc)
# My Question: (Code down below doesn't work, it's for example)
def SomeotherFunc(self):
self.somefunc.widget1.Show()
self.somefunc.widget1.Show()
self.somefunc.widget1.Show()
self.somefunc.widget4.setHidden()
self.somefunc.widget5.setHidden()
Full Code:
import sys
from PyQt4 import QtGui, QtCore
import resources
class Window(QtGui.QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.setGeometry(0, 0, 1280, 800)
self.setWindowTitle("E.S Quiz")
self.home()
def home(self):
pic = QtGui.QLabel(self)
pic.setGeometry(0, 0, 1280, 800)
pic.setPixmap(QtGui.QPixmap(":/images/background.png"))
btn = QtGui.QPushButton("", self)
btn.resize(150, 120)
btn.move(600, 400)
btn.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
btn.setObjectName('btn')
btn.setStyleSheet("#btn {background-image: url(':/images/Button1.png'); border: none; }"
"#btn:hover { background-image: url(':/images/Button1Hover.png'); }"
"#btn:pressed { background-image: url(':/images/Button1Press.png'); }")
btn.clicked.connect(self.test)
self.show()
def test(self):
print "Here"
def startup():
app = QtGui.QApplication(sys.argv)
GUI = Window()
sys.exit(app.exec_())
startup()
Question:
How do i modify some functions widgets from another function?
You need to store references to the subwidgets on the main window using self
def func(self):
self.btn = QPushButton(...)
...
def other_func(self):
self.btn.setText('Hello')
I've edited your code. I believe this will do the job. Just push the button, and see the label disappear. Have fun :-)
import sys
from PyQt4 import QtGui, QtCore
class Window(QtGui.QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.setGeometry(40, 80, 1280, 800)
# You should make a 'mainWidget' that
# serves as a container for all your other
# widgets.
self.mainWidget = QtGui.QWidget()
self.setCentralWidget(self.mainWidget)
self.setWindowTitle("E.S Quiz")
self.home()
self.show()
def home(self):
# Make the label
pic = QtGui.QLabel(parent = self.mainWidget)
pic.setText("My label")
pic.setGeometry(0, 0, 1280, 800)
#pic.setPixmap(QtGui.QPixmap(":/images/background.png"))
# Make a label that will disappear when
# you push the button.
self.myLabel = QtGui.QLabel(parent = self.mainWidget)
self.myLabel.setText("My removable label")
self.myLabel.setGeometry(40,40,200,100)
# Make the button
self.btn = QtGui.QPushButton(parent = self.mainWidget)
self.btn.setCheckable(True)
self.btn.setText("My button")
self.btn.resize(150, 120)
self.btn.move(600, 400)
self.btn.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
self.btn.setObjectName('btn')
# self.btn.setStyleSheet("#btn {background-image: url(':/images/Button1.png'); border: none; }"
# "#btn:hover { background-image: url(':/images/Button1Hover.png'); }"
# "#btn:pressed { background-image: url(':/images/Button1Press.png'); }")
self.btn.clicked.connect(self.btnAction)
def btnAction(self, pressed):
print("Button pushed")
if(pressed):
self.myLabel.setVisible(False)
else:
self.myLabel.setVisible(True)
def startup():
app = QtGui.QApplication(sys.argv)
GUI = Window()
sys.exit(app.exec_())
startup()
Related
I have seen other examples of this but they use
class secondWindow():
def __init__(self):
super().__init__()
#some code
class Window():
def __init__(self):
super().__init__()
# some code
def main():
app = QtGui.QApplication(sys.argv)
main = Window()
main.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
however my code looks like this
class secondWindow():
def __init__(self):
some code
class overviewWindow():
def __init__(self):
# Database setup
conn = None
try:
conn = sqlite3.connect("exercises.db")
print("[*] Connected successfully to the database")
except:
print("[*] Error connecting to the databse")
# Window setup
self.app = QApplication(sys.argv)
self.w = QWidget()
self.w.resize(winWidth, winHeight)
self.w.move(200, 20)
self.w.setWindowTitle("Test")
self.w.setStyleSheet("background-color: #F4F0BB")
self.w.show()
self.showUI()
sys.exit(self.app.exec_())
def showUI(self):
# Title
self.title = QLabel()
self.title.setParent(self.w)
self.title.setText("Overblik")
self.title.resize(winWidth, 100)
self.title.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
self.title.setStyleSheet("font-size: 45pt")
self.title.show()
self.frame = QFrame()
self.frame.resize(winWidth, 900)
self.frame.move(0, 100)
self.frame.setParent(self.w)
self.frame.show()
# Buttons
xBuffer = 130
yBuffer = 130
sum = 0
for i in range(0, 6):
for j in range(0, 4):
sum += 1
self.button2 = Button(self.frame, 75+(j*xBuffer), 75+(i*yBuffer), str(sum))
if __name__ == "__main__":
overviewWindow()
My problem is i want to open a second window with the same window style (same background and size) as the first but with different content i.e. different labels and buttons
I have tried modifying my code so it looks like the other examples but i cant figure out how to rewrite it without rewriting my entire file.
Try having all your styles and customization in a stylesheet that way you can apply the style to all classes you need to without individually changing elements here is an example:
from PySide2 import QtCore
from PySide2.QtWidgets import *
from PySide2.QtGui import *
class Widget2(QWidget):
def __init__(self, parent=None):
super(Widget2, self).__init__(parent)
self.gui()
def gui(self):
self.w1 = self
self.w1.setAutoFillBackground(True)
self.w1.setWindowTitle("")
self.w1.resize(500, 450)
self.w1.setCursor(Qt.ArrowCursor)
self.w1.setToolTip("")
self.check1 = QCheckBox("Check Box", self.w1)
self.check1.setChecked(0)
self.check1.move(180, 220)
self.check1.resize(90, 22)
self.check1.setCursor(Qt.ArrowCursor)
self.check1.setToolTip("")
self.button2 = QToolButton(self.w1)
self.button2.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
self.button2.setText("Button")
self.button2.move(40, 110)
self.button2.resize(90, 22)
self.button2.setCursor(Qt.ArrowCursor)
self.button2.setToolTip("")
return self.w1
class Widget1(QWidget):
def __init__(self, parent=None):
super(Widget1, self).__init__(parent)
self.gui()
def gui(self):
self.w1 = self
self.w1.setAutoFillBackground(True)
self.w1.setWindowTitle("")
self.w1.resize(500, 450)
self.w1.setCursor(Qt.ArrowCursor)
self.w1.setToolTip("")
self.button1 = QToolButton(self.w1)
self.button1.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
self.button1.setText("Button")
self.button1.move(40, 110)
self.button1.resize(90, 22)
self.button1.setCursor(Qt.ArrowCursor)
self.button1.setToolTip("")
self.button1.clicked.connect(self.event)
return self.w1
def event(self):
b = Widget2()
b.setStyleSheet("""
QToolButton
{
color: yellow;
background-color: red;
}""")
b.show()
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
a = Widget1()
a.setStyleSheet("""
QToolButton
{
color: yellow;
background-color: red;
}""")
a.show()
sys.exit(app.exec_())
As you can see I have one stylesheet that is applied to both of my QWidgets, ideally you would apply the stylesheet to QApplication but I could not reproduce an example of it working.
If your window opens and closes straight away try having this in the event function instead:
def event(self):
if self.w is None:
self.w = SecondWindow()
self.w.show()
Or have self.w = SecondWindow() in the main function and then in the event have the self.w.show().
So like this:
class Second(QtGui.QMainWindow):
some code
class First(QtGui.QMainWindow):
def __init__(self, parent=None):
some code
self.w = SecondWindow()
def on_pushButton_clicked(self):
self.w.show()
I have a code to generate a GUI with PyQt5 that enables a user to create multiple buttons (QPushButton) based on an entry (QLineEdit), and to delete these buttons when pressing an "X" button (deleteLater()).
My problem is that when deleting some of these buttons by pressing the associated X-button, this leaves a small empty space where the buttons were initially, and I therefore wonder how to remove these spaces?
Image of the empty spaces
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QLineEdit, QWidget, QVBoxLayout, QHBoxLayout, QGridLayout, QGroupBox, QScrollArea, QLabel
from PyQt5.QtCore import Qt
import sys
class MyWindow(QMainWindow):
def __init__(self):
super(MyWindow, self).__init__()
self.setWindowTitle("My Program")
self.setGeometry(100, 100, 1500, 1500)
self.initUI()
def initUI(self):
widgets = MainWidgets()
self.setCentralWidget(widgets)
class MainWidgets(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.grid = QGridLayout()
self.grid.setColumnStretch(0, 1)
self.grid.setColumnStretch(1, 1)
self.grid.setColumnStretch(2, 1)
self.grid.setColumnStretch(3, 1)
self.grid.setColumnStretch(4, 1)
self.groupBox = QGroupBox("Labels")
self.groupBox.setStyleSheet('''
QGroupBox::title {
subcontrol-position: top center;
}
''')
right_column_layout = QVBoxLayout(self.groupBox)
scrollArea = QScrollArea()
scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
scrollArea.setWidgetResizable(True)
right_column_layout.addWidget(scrollArea)
scrollArea.setWidget(RightColWidgets())
self.grid.addWidget(self.groupBox, 0, 5, 1, 5)
self.setLayout(self.grid)
class RightColWidgets(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.layout = QVBoxLayout(self)
self.labelEntry = QLineEdit(self)
self.addLabelButton = QPushButton(self)
self.addLabelButton.setText("Add Label")
self.addLabelButton.clicked.connect(self.addNewLabel)
self.emptyspace = QLabel(self)
self.layout.addWidget(self.labelEntry, stretch=0)
self.layout.addWidget(self.addLabelButton, stretch=0)
self.layout.addWidget(self.emptyspace, stretch=1)
def addNewLabel(self):
labelname = self.labelEntry.text()
newLabelItems = Labels(self, labelname)
self.layout.insertWidget(2, newLabelItems)
class Labels(QWidget):
def __init__(self, parent, labelname, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
self.mylabelname = labelname
self.initUI()
def initUI(self):
self.labelButton = QPushButton(self)
self.labelButton.setText(str(self.mylabelname))
self.labelButton.setStyleSheet("""
QPushButton {border: 1px solid back; background: rgba(103, 186, 181, 0.5); padding-top: 10px; padding-bottom: 10px}
""")
self.labelButton.clicked.connect(self.printbutton)
self.buttonErase = QPushButton(self)
self.buttonErase.setText("X")
self.buttonErase.setStyleSheet("""
QPushButton {border: 1px solid back; padding-right: 5 px; padding-left: 5 px; padding-top: 10px; padding-bottom: 10px}
""")
self.buttonErase.clicked.connect(self.erasebutton)
layout = QHBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.addWidget(self.labelButton, stretch=1)
layout.addWidget(self.buttonErase, stretch=0)
def printbutton(self):
print('clicked:', self.labelButton.text())
def erasebutton(self):
self.labelButton.deleteLater()
self.buttonErase.deleteLater()
if __name__ == '__main__':
app = QApplication(sys.argv)
# app.setStyle('Fusion')
window = MyWindow()
window.showMaximized()
sys.exit(app.exec_())
Deleting the children does not delete the container, so what you see is the empty Labels widget with the spacing of its layout contentsMargins().
A simple solution could be to directly connect the button with its own deleteLeter(), which automatically deletes its children:
self.buttonErase.clicked.connect(self.deleteLater)
A better solution would be to connect the signal to the parent and let it do everything necessary in a cleaner way, as you might need to keep track of the existing widgets (for instance, to remove them from the list of currently existing labels):
class RightColWidgets(QWidget):
# ...
def addNewLabel(self):
labelname = self.labelEntry.text()
newLabelItems = Labels(self, labelname)
self.layout.insertWidget(2, newLabelItems)
newLabelItems.buttonErase.clicked.connect(
lambda: self.deleteLabel(newLabelItems))
def deleteLabel(self, widget):
self.layout.removeWidget(widget)
widget.deleteLater()
Obviously, in this case you don't need to connect the clicked signal in the initUi of the Label class anymore.
Note that layout() is an existing (and dynamic) property of any QWidget, so you should not overwrite it.
I want to make a specific button in PyQt toolbar appeared as pressed(with blue background). Suppose when I hit the toolbar button I want it to be appeared as pressed
import sys
from PyQt4 import QtGui, QtCore
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class Window(QtGui.QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.setGeometry(50, 50, 700, 700)
self.setWindowTitle('Rich Text Editor')
self.statusBar = QStatusBar()
self.textEdit = QtGui.QTextEdit()
self.setCentralWidget(self.textEdit)
self.setStatusBar(self.statusBar)
self.home()
def home(self):
changeBoldActionTB = \
QtGui.QAction(QtGui.QIcon('bold-text-option.png'),
'Make the text bold', self)
changeBoldActionTB.triggered.connect(self.changeBold)
self.formatbar = QToolBar()
self.addToolBar(Qt.TopToolBarArea, self.formatbar)
self.formatbar.addAction(changeBoldActionTB)
self.show()
def changeBold(self):
pass
#I think this does't matter
def run():
app = QtGui.QApplication(sys.argv)
GUI = Window()
sys.exit(app.exec_())
run()
I have two toolbars.I am planning to use cursorPositionChanged to do this but still is there a way in PyQt to do this
reproduible code:
https://files.fm/u/h4c2amdx
Instead of using QAction you must use QToolButton and set the checkable property to True:
toolButton.setCheckable(True)
Example:
class Window(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.setWindowTitle('Rich Text Editor')
self.statusBar = QStatusBar(self)
self.textEdit = QtGui.QTextEdit(self)
self.setCentralWidget(self.textEdit)
self.setStatusBar(self.statusBar)
self.home()
def home(self):
toolButton = QToolButton(self)
toolButton.setIcon(QtGui.QIcon('bold-text-option.png'))
toolButton.setCheckable(True)
toolButton.toggled.connect(self.onToggled)
self.formatbar = QToolBar(self)
self.addToolBar(Qt.TopToolBarArea, self.formatbar)
self.formatbar.addWidget(toolButton)
def onToggled(self, checked):
print(checked)
Screenshots:
Plus: To set the value manually and to obtain the status the following instructions are used:
toolButton.setChecked(True) # set State
print(toolButton.isChecked()) # get State
toolButton.toggle() # change state
Actions also have a checable flag and they can act as a toggle switch. Sorry, I don’t know English. So I showed it with code.
# add this code before self.formatbar = QToolBar()
# and create img file blue_bold-text-option.png
self.changeBoldActionTB.setCheckable(True)
icon = QIcon()
icon.addFile('bold-text-option.png', QSize(), QIcon.Normal, QIcon.Off)
icon.addFile('blue_bold-text-option.png', QSize(), QIcon.Normal, QIcon.On)
self.changeBoldActionTB.setIcon(icon)
I have a pushbutton to add a tab in a QTabWidget. But when I change the button's size, it's not in the corner anymore. So how can I bring it to the corner like in the first picture?
Not change size:
Change size:
Here is my code:
from PyQt4 import QtGui, QtCore
class PlaylistTable(QtGui.QWidget):
def __init__(self):
super(PlaylistTable, self).__init__()
self.playlistTable = QtGui.QTableWidget(self)
self.playlistTable.setFrameShape(QtGui.QFrame.NoFrame)
self.playlistTable.setFrameShadow(QtGui.QFrame.Sunken)
self.playlistTable.setLineWidth(0)
self.playlistTable.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
self.playlistTable.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel)
self.playlistTable.setHorizontalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel)
self.playlistTable.setShowGrid(True)
self.playlistTable.setGridStyle(QtCore.Qt.SolidLine)
self.playlistTable.setWordWrap(True)
self.playlistTable.setCornerButtonEnabled(True)
self.playlistTable.verticalHeader().setVisible(False)
class CustomTabWidget(QtGui.QTabWidget):
"""Tab Widget that that can have new tabs easily added to it."""
def __init__(self, parent=None):
super(CustomTabWidget, self).__init__(parent)
# QtGui.QTabWidget.__init__(self, parent)
# Tab Bar
self.tab = QtGui.QTabBar()
self.setTabBar(self.tab)
# Properties
self.setMovable(True)
self.setTabsClosable(True)
self.plusButton = QtGui.QPushButton("+")
self.plusButton.setFixedSize(QtCore.QSize(22, 22))
self.setCornerWidget(self.plusButton)
# Signals
self.connect(self.plusButton, QtCore.SIGNAL('clicked()'), self.addTab)
# self.tab.plusClicked.connect(self.addTab)
self.tab.tabMoved.connect(self.tab.moveTab)
self.tabCloseRequested.connect(self.removeTab)
def addTab(self):
string = QtCore.QString.fromUtf8("Playlist")
tab = PlaylistTable()
super(CustomTabWidget, self).addTab(tab, string)
class AppDemo(QtGui.QMainWindow):
def __init__(self):
super(AppDemo, self).__init__()
self.centralwidget = QtGui.QWidget(self)
self.horizontalLayout = QtGui.QHBoxLayout(self.centralwidget)
self.horizontalLayout.setContentsMargins(0, -1, 0, -1)
self.playlist_manager = CustomTabWidget(self.centralwidget)
self.horizontalLayout.addWidget(self.playlist_manager)
self.playlist_manager.addTab()
self.setCentralWidget(self.centralwidget)
self.show()
# end class AppDemo
def main():
import sys
app = QtGui.QApplication(sys.argv)
w = AppDemo()
w.setWindowTitle('AppDemo')
w.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
I'm guessing the reason is this, from QTabWidget Documentation:
The geometry of the widget is determined
based on the widget's sizeHint() and the style().
If you print the sizeHint() of the QPushButton you will see that width never goes below a certain value.
I've found an alternative is to use a QToolButton which can do everything (even more) a QPushButton does.
self.plusButton = QtGui.QToolButton(self)
self.plusButton.setText("+")
I started reading the zetcode tutorial for PyQt4 (http://zetcode.com/tutorials/pyqt4/firstprograms/) and I was doing the tooltip part and all I did was copy and paste this bit of code. When I went to run it, the push button did not display in the window. Any reason as to why this might be? new to PyQt4 and Qt in general.
import sys
from PyQt4 import QtGui
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
QtGui.QToolTip.setFont(QtGui.QFont('SansSerif', 10))
self.setToolTip('This is a <b>QWidget</b> widget')
btn = QtGui.QPushButton('Button, self')
btn.setToolTip('This is a <b>QPushButton</b> widget')
btn.resize(btn.sizeHint())
btn.move(50, 50)
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('Tooltips')
self.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Replace following line:
btn = QtGui.QPushButton('Button, self')
with:
btn = QtGui.QPushButton('Button', self)
btn = QtGui.QPushButton('Button, self')
supposed to be:
btn = QtGui.QPushButton('Button', self)