The code below creates a QListWidget with QListWidgetItem assigned a thumb image.
I would appreciate if you show how to make a color border around of the QListWidgetItem
Here is the Photoshoped image showing a concept:
from PyQt4 import QtGui, QtCore
import sys, os
class MyClassItem(QtGui.QListWidgetItem):
def __init__(self, parent=None):
super(QtGui.QListWidgetItem, self).__init__(parent)
class ThumbListWidget(QtGui.QListWidget):
def __init__(self, type, parent=None):
super(ThumbListWidget, self).__init__(parent)
self.setIconSize(QtCore.QSize(64, 64))
class Dialog_01(QtGui.QMainWindow):
def __init__(self):
super(QtGui.QMainWindow,self).__init__()
self.listItems={}
myQWidget = QtGui.QWidget()
myBoxLayout = QtGui.QVBoxLayout()
myQWidget.setLayout(myBoxLayout)
self.setCentralWidget(myQWidget)
self.listWidgetA = ThumbListWidget(self)
for i in range(7):
listItemAInstance=MyClassItem()
name='A'+'%04d'%i
listItemAInstance.setText(name)
listItemAInstance.setBackgroundColor(QtCore.Qt.darkGray)
if i%2: listItemAInstance.setBackgroundColor(QtCore.Qt.gray)
icon=self.getIcon(name)
listItemAInstance.setIcon( icon )
self.listWidgetA.addItem(listItemAInstance)
listItemBInstance=MyClassItem()
name='B'+'%04d'%i
listItemBInstance.setText(name)
icon=self.getIcon(name)
listItemBInstance.setIcon( icon )
myBoxLayout.addWidget(self.listWidgetA)
def getIcon(self, name):
thumbpath=os.path.expanduser("~")+'/thumbs/' +name+'/'+name+'.jpg'
if not thumbpath: return
if not os.path.exists(os.path.dirname(thumbpath)):
os.makedirs(os.path.dirname(thumbpath))
img = QtGui.QImage(64, 64, QtGui.QImage.Format_RGB32)
img.fill(QtGui.QColor(96,96,96))
painter = QtGui.QPainter(img)
font = painter.font()
font.setBold(True)
font.setPointSize(18)
painter.setPen(QtGui.QColor('black'))
painter.setFont(font)
painter.drawText(img.rect(), QtCore.Qt.AlignCenter, name)
painter.end()
img.save(thumbpath, 'JPG')
icon = QtGui.QIcon( thumbpath )
pixmap = icon.pixmap(64, 64)
icon = QtGui.QIcon(pixmap)
return icon
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
dialog_1 = Dialog_01()
dialog_1.show()
dialog_1.resize(720,480)
sys.exit(app.exec_())
Every class that derives from QWidget supports CSS styling. What you could do is something such as:
lwi = QListWidget()
lwi.setStyleSheet("QListWidget::item { border: 0px solid red }")
For more info, see http://qt-project.org/doc/qt-4.8/qwidget.html#styleSheet-prop
You can also style your entire application, but apply a certain part of styling only to QListWidgetItem by putting it as a prefix.
C++ example I found:
app.setStyleSheet("QListWidget { background: red; } QListWidget::item { background: yellow; } QListWidget::item:selected { background: blue; }");
Related
My attempt is to try to import modules and their depending classes dynamically. Here is my code. File "Sample_tabwidget_base.py" have three classes names "Contact", "Personal" and "Educational". And I need to import all those classes into my file "sample_tabwidget.py" dynamically. Googleing so many items and trying them, But lack of knowledge, I can't succeed.
File : sample_tabwidget.py
import sys
from PyQt5.QtWidgets import *
# from sample_tabwidget_base import *
import importlib
module = importlib.import_module('sample_tabwidget_base')
print(module.__doc__)
# class_ = getattr(module)
# module = __import__("sample_tabwidget_base")
# mod = getattr(module,'Contact')
# print(mod)
class MainPage(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("QTabWidget Samples")
self.showMaximized()
self.subwindow = None
self.Ui()
self.show()
def Ui(self):
self.tab = QTabWidget()
self.tab.setTabsClosable(True)
self.tab.setTabShape(QTabWidget.Rounded)
self.tab.setTabPosition(QTabWidget.North)
self.tab.setMovable(True)
self.tab.setDocumentMode(True)
self.tab.setAutoFillBackground(True)
self.tab.setStyleSheet(stylesheet())
font = self.tab.font()
font.setPointSize(10)
self.tab.setFont(font)
self.right_layout = QHBoxLayout()
self.main_layout = QHBoxLayout()
self.right_frame = QFrame()
self.right_frame.setObjectName("rightframe")
self.right_frame.setStyleSheet(f"QFrame#rightframe{{background-color: lightgreen;}}")
self.right_frame.setContentsMargins(0,0,0,0)
self.right_frame.setLayout(self.right_layout)
self.right_layout.setContentsMargins(15,0,0,0)
self.right_layout.addWidget(self.tab)
self.main_layout.setContentsMargins(0,0,0,0)
self.main_layout.addWidget(self.right_frame)
self.main_layout.addStretch()
self.contacttab = Contact()
self.personaltab = Personal()
self.educationaltab = Educational()
self.setLayout(self.main_layout)
self.tab.addTab(self.contacttab, "Contacts")
self.tab.addTab(self.personaltab,"Personal")
self.tab.addTab(self.educationaltab,"Educational")
def stylesheet():
return """
QTabBar {background-color: grey;}
QTabWidget::pane {border: 0px solid yellow; top:-1px; background: grey; }
QTabBar::tab:hover{background-color:yellow;}
QTabBar::tab {background-color: grey; color : black;
border-left: 1px solid grey;border-top:1px solid grey;border-right:1px solid grey;
text-align:centre ; font-family:Trebuchet MS; padding : 10px; }
QTabBar::tab:selected {background: lightgrey;color : Black;border-bottom:5px solid red;margin-bottom: -1px;
text-align:centre ; font-family:Trebuchet MS; color:Black; padding : 10px;}
"""
if __name__ == "__main__":
app = QApplication(sys.argv)
mainwindow = MainPage()
app.setStyle("windows vista")
mainwindow.show()
sys.exit(app.exec_())
File : smaple_tabwidget_base.py
import sys
from PyQt5.QtWidgets import *
class Contact(QWidget):
def __init__(self):
super().__init__()
print("its a contact class")
self.setWindowTitle("Contact Details")
self.layout = QFormLayout()
self.layout.addRow("Name", QLineEdit())
self.layout.addRow("Address", QLineEdit())
self.setLayout(self.layout)
class Personal(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Personal Details")
self.layout = QFormLayout()
self.sex = QHBoxLayout()
self.sex.addWidget(QRadioButton("Male"))
self.sex.addWidget(QRadioButton("Female"))
self.layout.addRow(QLabel("Sex"), self.sex)
self.layout.addRow("Date of Birth", QLineEdit())
self.setLayout(self.layout)
class Educational(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Educational Details")
self.layout = QHBoxLayout()
self.layout.addWidget(QLabel("subjects"))
self.layout.addWidget(QCheckBox("Physics"))
self.layout.addWidget(QCheckBox("Maths"))
self.setLayout(self.layout)
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'm trying to create Login Window, which has QLineEdit below QLabel, but the current QLabel taking too many space in Window, i don't know why, here is the picture :
QLabel { background-color: red; }
My Code :
self.text = QLabel("LOGIN")
# self.text.setStyleSheet("QLabel { background-color: red; color : white;margin-top: 50px;margin-bottom: 0px; }")
self.text.setAlignment(Qt.AlignCenter)
# self.text.setContentsMargins(0, 0, 0, 0)
# self.text.setGeometry(QRect(10,10,30,80))
font = QFont("Sans-Serif", 30)
self.text.setFont(font)
form = QLineEdit("Write my name here..")
form.setAlignment(Qt.AlignCenter)
# form.setAlignment(Qt.AlignHCenter)
self.layout = QVBoxLayout()
# self.layout.setContentsMargins(0, 0, 0, 0)
self.layout.setSpacing(0)
self.layout.addWidget(self.text)
self.layout.addWidget(form)
self.layout.addWidget(self.button)
self.setLayout(self.layout)
I do not see the relationship between the code provided by the OP and the LOGIN window from which you want to copy the structure, so create the following code from scratch.
from PySide2 import QtCore, QtGui, QtWidgets
class LoginPage(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.image_label = QtWidgets.QLabel(alignment=QtCore.Qt.AlignCenter)
self.login_label = QtWidgets.QLabel(
text=self.tr("LOG IN"), alignment=QtCore.Qt.AlignCenter
)
self.email_username_lineedit = QtWidgets.QLineEdit(
placeholderText=self.tr("Email or username")
)
self.password_lineedit = QtWidgets.QLineEdit(
placeholderText=self.tr("Password"), echoMode=QtWidgets.QLineEdit.Password
)
self.enter_button = QtWidgets.QPushButton(self.tr("Enter"))
self.forgot_password_label = QtWidgets.QLabel(
self.tr("Forgot password?"), alignment=QtCore.Qt.AlignCenter
)
self.image_label.setPixmap(QtGui.QPixmap("so-icon.png"))
# font = self.
font = self.login_label.font()
font.setPointSize(30)
self.login_label.setFont(font)
self.login_label.setSizePolicy(
QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed
)
self.forgot_password_label.setSizePolicy(
QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed
)
lay = QtWidgets.QVBoxLayout(self)
lay.setSpacing(0)
lay.addWidget(self.image_label)
lay.addWidget(self.login_label)
lay.addWidget(self.email_username_lineedit)
lay.addWidget(self.password_lineedit)
lay.addWidget(self.enter_button)
lay.addWidget(self.forgot_password_label)
self.resize(320, 480)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = LoginPage()
w.show()
sys.exit(app.exec_())
The following code implements 5 movable labels. When I try to change the color of the labels while they are being moved, the labels snap back to the original position when the mouse button is released. When you comment out the part where setStyleSheet is used, it works and the labels are able to move and be released freely.
import sys
from PySide import QtGui
from PySide import QtCore
from PySide.QtGui import *
from PySide.QtCore import *
from Drag import Ui_Dialog
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.mainMenuWidget = MainStack(self)
self.setCentralWidget(self.mainMenuWidget)
self.show()
class MainStack(QWidget):
def __init__(self,parent=None):
super(MainStack,self).__init__(parent)
self.initUI()
def initUI(self):
layout = QVBoxLayout(self)
self.stack = QStackedWidget(parent=self)
self.dragPage = DragClass()
#Add Pages to Stack
self.stack.addWidget(self.dragPage)
#Add Stack to Layout
self.stack.setCurrentWidget(self.dragPage)
layout.addWidget(self.stack)
class DragClass(QDialog):
def __init__(self, parent=None):
super(DragClass, self).__init__(parent)
self.LabelGrid = Ui_Dialog()
self.LabelGrid.setupUi(self)
self.configureLabels()
def configureLabels(self):
labels = (self.LabelGrid.verticalLayout.itemAt(i) for i in range(self.LabelGrid.verticalLayout.count()))
for label in labels:
label = label.widget()
if (isinstance(label,DragButton)) :
label.setSizePolicy(QSizePolicy.Preferred,QSizePolicy.Expanding)
label.setStyleSheet("""
background-color: lightblue;
border-width: 2px;
border-style: solid;
border-color: black;
margin: 2px;
""")
#########DragButton Class#############
class DragButton(QLabel):
def mousePressEvent(self, event):
self.__mousePressPos = None
self.__mouseMovePos = None
if event.button() == QtCore.Qt.LeftButton:
self.__mousePressPos = event.globalPos()
self.__mouseMovePos = event.globalPos()
self.start_move = 0
super(DragButton, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
if event.buttons() == QtCore.Qt.LeftButton:
# adjust offset from clicked point to origin of widget
currPos = self.mapToGlobal(self.pos())
globalPos = event.globalPos()
diff = globalPos - self.__mouseMovePos
newPos = self.mapFromGlobal(currPos + diff)
self.move(newPos)
self.__mouseMovePos = globalPos
#If you Uncomment these blocks, the labels are no longer able to move freely. They snap back to their original position when released
#if not self.start_move:
#self.setStyleSheet("background-color: red;")
#if not self.start_move:
#self.start_move = 1
super(DragButton, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
if self.__mousePressPos is not None:
#if self.start_move:
#self.setStyleSheet("background-color: lightblue;")
moved = event.globalPos() - self.__mousePressPos
if moved.manhattanLength() > 3:
event.ignore()
return
super(DragButton, self).mouseReleaseEvent(event)
##############################################
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWin = MainWindow()
ret = app.exec_()
sys.exit( ret )
UI Class for the draggable labels:
from PySide import QtCore, QtGui
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(400, 300)
self.gridLayout = QtGui.QGridLayout(Dialog)
self.gridLayout.setObjectName("gridLayout")
self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.option1 = DragButton(Dialog)
font = QtGui.QFont()
font.setWeight(75)
font.setBold(True)
self.option1.setFont(font)
self.option1.setFrameShape(QtGui.QFrame.StyledPanel)
self.option1.setFrameShadow(QtGui.QFrame.Raised)
self.option1.setAlignment(QtCore.Qt.AlignCenter)
self.option1.setObjectName("option1")
self.verticalLayout.addWidget(self.option1)
self.option2 = DragButton(Dialog)
font = QtGui.QFont()
font.setWeight(75)
font.setBold(True)
self.option2.setFont(font)
self.option2.setFrameShape(QtGui.QFrame.StyledPanel)
self.option2.setFrameShadow(QtGui.QFrame.Raised)
self.option2.setAlignment(QtCore.Qt.AlignCenter)
self.option2.setObjectName("option2")
self.verticalLayout.addWidget(self.option2)
self.Option3 = DragButton(Dialog)
font = QtGui.QFont()
font.setWeight(75)
font.setBold(True)
self.Option3.setFont(font)
self.Option3.setFrameShape(QtGui.QFrame.StyledPanel)
self.Option3.setFrameShadow(QtGui.QFrame.Raised)
self.Option3.setAlignment(QtCore.Qt.AlignCenter)
self.Option3.setObjectName("Option3")
self.verticalLayout.addWidget(self.Option3)
self.Option4 = DragButton(Dialog)
font = QtGui.QFont()
font.setWeight(75)
font.setBold(True)
self.Option4.setFont(font)
self.Option4.setFrameShape(QtGui.QFrame.StyledPanel)
self.Option4.setFrameShadow(QtGui.QFrame.Raised)
self.Option4.setLineWidth(1)
self.Option4.setMidLineWidth(0)
self.Option4.setAlignment(QtCore.Qt.AlignCenter)
self.Option4.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
self.Option4.setObjectName("Option4")
self.verticalLayout.addWidget(self.Option4)
self.Option5 = DragButton(Dialog)
font = QtGui.QFont()
font.setWeight(75)
font.setBold(True)
self.Option5.setFont(font)
self.Option5.setFrameShape(QtGui.QFrame.StyledPanel)
self.Option5.setFrameShadow(QtGui.QFrame.Raised)
self.Option5.setLineWidth(1)
self.Option5.setMidLineWidth(0)
self.Option5.setAlignment(QtCore.Qt.AlignCenter)
self.Option5.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
self.Option5.setObjectName("Option5")
self.verticalLayout.addWidget(self.Option5)
self.gridLayout.addLayout(self.verticalLayout, 0, 0, 1, 1)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
self.option1.setText(QtGui.QApplication.translate("Dialog", "Option 1", None, QtGui.QApplication.UnicodeUTF8))
self.option2.setText(QtGui.QApplication.translate("Dialog", "Option 2", None, QtGui.QApplication.UnicodeUTF8))
self.Option3.setText(QtGui.QApplication.translate("Dialog", "Option 3", None, QtGui.QApplication.UnicodeUTF8))
self.Option4.setText(QtGui.QApplication.translate("Dialog", "Option 4", None, QtGui.QApplication.UnicodeUTF8))
self.Option5.setText(QtGui.QApplication.translate("Dialog", "Option 5", None, QtGui.QApplication.UnicodeUTF8))
from app import DragButton
Whenever a widget is added to a layout, its size and position is decided by that layout (according to the available size and other widgets that are part of the layout).
While it is possible to change the geometry of a widget while it's part of a layout, any change to its contents will automatically be notified to the layout, that will then update itself accordingly.
Those changes include different size, different constraints (minimum/maximum size), the size policy (the ability to expand or shrink).
When a stylesheet is set to a widget, its content are immediately invalidated and computed again (even if the stylesheet is the same); the reason for which you can't move the widget is that as soon as the stylesheet is applied, the layout that contains it will force it again to its original position.
You can see what happens if you keep the commented lines, move a widget and then resize the window: the moved widget will be repositioned again as the layout requires.
If you want to be able to move a widget freely you need to create the movable widgets as children of the widget that will contain them, but not in a layout.
This obviously becomes a problem if you want to "lay out" them similarly to how a real QLayout would, but within the resizeEvent of the widget that contains them.
In this specific case:
class DragClass(QDialog):
def __init__(self, parent=None):
super(DragClass, self).__init__(parent)
self.LabelGrid = Ui_Dialog()
self.LabelGrid.setupUi(self)
self.configureLabels()
def configureLabels(self):
# Note that since the labels are not part of a layout anymore, now, I
# had to use another way to "find them". Normally one would go with
# findChildren, but that's not our case because of the way the DragButton
# class is imported (it actually is snap.DragButton)
self.labels = [child for child in self.children() if child.__class__.__name__ == 'DragButton']
for label in self.labels:
if (isinstance(label,DragButton)) :
label.setSizePolicy(QSizePolicy.Preferred,QSizePolicy.Expanding)
label.setStyleSheet("""
background-color: lightblue;
border-width: 2px;
border-style: solid;
border-color: black;
margin: 2px;
""")
def resizeEvent(self, event):
margin = 5
spacing = 4
innerRect = self.rect().adjusted(margin, margin, -margin, -margin)
count = len(self.labels)
availableHeight = innerRect.height() - spacing * (count - 1)
labelSize = availableHeight / count
top = innerRect.y()
left = innerRect.left()
width = innerRect.width()
for label in self.labels:
rect = QtCore.QRect(left, top, width, labelSize)
label.setGeometry(rect)
top = rect.bottom() + spacing
In this way, the labels are aligned to a "virtual" layout when shown the first time, but now can be freely moved around. Obviously, with this simple implementation, as soon as the window is resized, they will be repositioned again, so it's up to you to decide what to do with labels that have been manually moved.
As a side note, you should not use a QDialog class for what you need. Dialogs are used as windows that appear over other existing windows. For your needs, a simple QWidget will suffice.
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()