How can I set x axis of the QLabel the exact center of the window? I have this example
from PyQt5.QtWidgets import QMainWindow,QApplication,QLabel
from PyQt5 import QtCore
import sys
class cssden(QMainWindow):
def __init__(self):
super().__init__()
self.mwidget = QMainWindow(self)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.setFixedSize(700,400)
self.label = QLabel(self)
self.label.setText("Center of the window")
self.label.setStyleSheet("color:green;"
"font: bold 20pt 'Arial'")
self.label.setGeometry(150,200,300,100)
self.show()
app = QApplication(sys.argv)
app.setStyleSheet("QMainWindow{background-color: rgb(30,30,30);border: 2px solid rgb(20,20,20)}")
ex = cssden()
sys.exit(app.exec_())
What to do on self.label.setGeometry so the label will be on the center of the window all the time? Is there a method like setCenter() ?
Use a vertical layout. The label will expand to fill the available space, and the text will be aligned centrally by default:
from PyQt5.QtWidgets import QWidget, QVBoxLayout
class cssden(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.setFixedSize(700,400)
self.label = QLabel(self)
self.label.setText("Center of the window")
self.label.setStyleSheet("color:green;"
"font: bold 20pt 'Arial'")
self.label.setAlignment(QtCore.Qt.AlignCenter)
widget = QWidget(self)
layout = QVBoxLayout(widget)
layout.addWidget(self.label)
self.setCentralWidget(widget)
self.show()
Related
I am trying to make a basic text editor with a toolbar, sidebar, and textbox. My program needs to use a QPushButton (which is in my 'toolbar' class) to make the text in my QTextEdit bold (in my TextEdit class). Here's an example snippet of code:
import sys
from PyQt5.QtWidgets import QPushButton, QTextEdit, QWidget, QMainWindow
from PyQt5.Qt import Qt, QApplication, QVBoxLayout, QHBoxLayout, QFrame, QFont
class ToolBar(QWidget):
def __init__(self):
super().__init__()
layout = QHBoxLayout()
self.btn = QPushButton(self, text="Bold")
layout.addWidget(self.btn)
self.italic = QPushButton(self, text="Italic")
layout.addWidget(self.italic)
t = TextEdit()
# This is the line that isn't working
self.btn.clicked.connect(lambda: t.set_bold())
# I've tried this without the lambda, and also with 'TextEdit.set_bold' but they didn't work
# It would also be nice to do the same for the italic buttons and other buttons in my toolbar
self.setLayout(layout)
class TextEdit(QWidget):
def __init__(self):
super().__init__()
self.textEdit = QTextEdit(self)
# self.set_bold() <-- If I were to run this, then the text box would become bold, so I know that it's not an error with the function
def set_bold(self):
# print("function activated") <-- This statement shows that the function is indeed executing
self.font = QFont("Helvetica", 14)
self.font.setBold(True)
self.textEdit.setFont(self.font)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
central_widget = QFrame()
layout = QVBoxLayout()
self.boldButton = ToolBar()
layout.addWidget(self.boldButton)
self.textBox = TextEdit()
layout.addWidget(self.textBox)
central_widget.setLayout(layout)
self.setCentralWidget(central_widget)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
I tried putting a print statement to confirm that the function is executing, which it is. I don't get any error messages so I can't seem to figure out what to do.
The connection must occur where the objects have a common scope, in this case within the MainWindow class.
class ToolBar(QWidget):
def __init__(self):
super().__init__()
self.bold_button = QPushButton(text="Bold")
self.italic_button = QPushButton(text="Italic")
layout = QHBoxLayout(self)
layout.addWidget(self.bold_button)
layout.addWidget(self.italic_button)
class TextEdit(QWidget):
def __init__(self):
super().__init__()
self.textEdit = QTextEdit(self)
def set_bold(self):
font = QFont("Helvetica", 14)
font.setBold(True)
self.textEdit.setFont(font)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.toolbar = ToolBar()
self.textBox = TextEdit()
central_widget = QFrame()
layout = QVBoxLayout(central_widget)
layout.addWidget(self.toolbar)
layout.addWidget(self.textBox)
self.setCentralWidget(central_widget)
self.toolbar.bold_button.clicked.connect(self.textBox.set_bold)
I am developing a scroll area widget with a height of 300 and adding QLabel Widgets in the scroll area, each QLabel height is 100. When adding more than 2 QLabel, the QLabel in the scroll area overlaps, and the scroll bar does not It shows that I have no way to pull the scroll bar. I want to separate the QLabel from each other. At the same time, I can pull down the scroll bar to see the remaining QLabel
from PyQt4 import QtCore
from PyQt4.QtGui import QScrollArea, QLabel, QVBoxLayout
import sys
from PyQt4 import QtGui
class ScrollArea(QScrollArea):
def __init__(self):
super(ScrollArea, self).__init__()
self.setFixedSize(500, 300)
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
vbox = QVBoxLayout()
self.setLayout(vbox)
for i in range(4):
lb = QLabel('hjkmlasda')
lb.setStyleSheet("""
border-width: 1px;
border-style: solid;
border-color:blue;
""")
lb.setFixedSize(400, 100)
vbox.addWidget(lb)
vbox.addStretch(1)
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
h = QtGui.QHBoxLayout()
h.addWidget(ScrollArea())
self.setLayout(h)
self.setGeometry(100, 100, 1000, 500)
self.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
You don't have to set a layout in the QScrollArea but a widget, so how do I put several widgets? Well, you must use a QWidget as a container and set the widget through a layout assigned to the container, and also enable the widgetResizable property:
class ScrollArea(QtGui.QScrollArea):
def __init__(self, parent=None):
super(ScrollArea, self).__init__(parent)
self.setFixedSize(500, 300)
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.setWidgetResizable(True)
container = QtGui.QWidget()
self.setWidget(container)
vbox = QtGui.QVBoxLayout(container)
# vbox.setSpacing(0)
for i in range(4):
lb = QtGui.QLabel("hjkmlasda")
lb.setStyleSheet(
"""
border-width: 1px;
border-style: solid;
border-color:blue;
"""
)
lb.setFixedSize(400, 100)
vbox.addWidget(lb)
You should set a resizable widget for the QScrollArea and place the layout on that widget. Edit the constructor as such:
class ScrollArea(QScrollArea):
def __init__(self):
super(ScrollArea, self).__init__()
w = QWidget()
self.setWidget(w)
self.setWidgetResizable(True)
self.setFixedSize(500, 300)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
vbox = QVBoxLayout(w)
. . .
I want to set the background for text, which means that I want to set the color of the rectangle contains the text. I have tested QPainter.setBackground, but it do not work. This is my code:
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class MyLabel(QLabel):
def __init__(self):
super(MyLabel, self).__init__()
self.setMinimumHeight(200)
self.setMinimumWidth(200)
def paintEvent(self, QPaintEvent):
super(MyLabel, self).paintEvent(QPaintEvent)
pos = QPoint(50, 50)
painter = QPainter(self)
brush = QBrush()
brush.setColor(QColor(255,0,0))
painter.setBackgroundMode(Qt.OpaqueMode)
painter.setBackground(brush)
painter.drawText(pos, 'hello,world')
class Window(QWidget):
def __init__(self):
super(Window, self).__init__()
layout = QHBoxLayout(self)
self.label = MyLabel()
layout.addWidget(self.label)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
What I want is:
Thanks for any help.
It is not necessary to implement a personalized QLabel, it is enough to set the background color through Qt Style Sheet, also do not use a layout if you want to establish a certain position
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.label = QtWidgets.QLabel("hello,world", self)
self.label.adjustSize()
self.label.setStyleSheet(
"background-color: {};".format(QtGui.QColor(255, 0, 0).name())
)
self.label.move(QtCore.QPoint(50, 50))
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.resize(640, 480)
window.show()
sys.exit(app.exec_())
I think it should be much easier to create a scrollable window in PyQt.
I have a list of labels that goes out of the window and I would like to scroll down to view them. At the moment the code does not give me an error, but the window just doesn't appear:
class Example(QWidget):
def __init__(self):
super().__init__()
layout = QVBoxLayout()
lbl_arr = makeLabelArr()
for i in range(1,8):
qb = lbl_arr[i]
# qb.setFixedWidth(300)
layout.addWidget(qb)
layout.setAlignment(Qt.AlignTop)
scroll = QScrollArea()
scroll.setWidget(self)
scroll.setWidgetResizable(True)
scroll.setFixedHeight(400)
layout.addWidget(scroll)
self.setLayout(layout)
self.setGeometry(0, 0, 600, 220)
self.setWindowTitle('SnP watchlist')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
#print(QDesktopWidget().availableGeometry())
ex = Example()
sys.exit(app.exec_())
Make the window itself a QScrollArea, like this:
class Window(QScrollArea):
def __init__(self):
super(Window, self).__init__()
widget = QWidget()
layout = QVBoxLayout(widget)
layout.setAlignment(Qt.AlignTop)
for index in range(100):
layout.addWidget(QLabel('Label %02d' % index))
self.setWidget(widget)
self.setWidgetResizable(True)
There is an example here: https://www.learnpyqt.com/tutorials/qscrollarea/
from PyQt5.QtWidgets import (QWidget, QSlider, QLineEdit, QLabel, QPushButton, QScrollArea,QApplication,
QHBoxLayout, QVBoxLayout, QMainWindow)
from PyQt5.QtCore import Qt, QSize
from PyQt5 import QtWidgets, uic
import sys
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.scroll = QScrollArea() # Scroll Area which contains the widgets, set as the centralWidget
self.widget = QWidget() # Widget that contains the collection of Vertical Box
self.vbox = QVBoxLayout() # The Vertical Box that contains the Horizontal Boxes of labels and buttons
for i in range(1,50):
object = QLabel("TextLabel: "+str(i))
self.vbox.addWidget(object)
self.widget.setLayout(self.vbox)
#Scroll Area Properties
self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.scroll.setWidgetResizable(True)
self.scroll.setWidget(self.widget)
self.setCentralWidget(self.scroll)
self.setGeometry(600, 100, 1000, 900)
self.setWindowTitle('Scroll Area Demonstration')
self.show()
return
def main():
app = QtWidgets.QApplication(sys.argv)
main = MainWindow()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
You should set layout after adding the scroll bar widget.
class Example(QWidget):
def __init__(self):
super().__init__()
layout = QVBoxLayout()
lbl_arr = makeArrayOfLabelsHTML()
for i in range(1,8):
qb = lbl_arr[i]
layout.addWidget(qb)
layout.setAlignment(Qt.AlignTop)
scroll = QScrollArea()
scroll.setWidget(self)
scroll.setWidgetResizable(True)
scroll.setFixedHeight(400)
layout.addWidget(scroll)
# set layout after adding scroll bar
self.setLayout(layout)
self.setGeometry(0, 0, 600, 220)
self.setWindowTitle('SnP watchlist')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
#print(QDesktopWidget().availableGeometry())
ex = Example()
sys.exit(app.exec_())
I have a list of texts, if the user search for a text in QLineEdit, I print the text. There is a QCompleter in QLineEdit.
The problem is, as we know Text and text are not same, but it's same to the user. So If user starts typing Text or text, I want to change it to the TEXT real time in QLineEdit. So whenever the user types a letter, I want to make it uppercase in QCompleter-QLineEdit. How can I do this? I have this atm;
from PyQt5.QtWidgets import QApplication,QPushButton,QMainWindow,QLabel,QLineEdit,QCompleter
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtCore import QPoint
import sys
class cssden(QMainWindow):
def __init__(self):
super().__init__()
self.mwidget = QMainWindow(self)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
#size
self.setFixedSize(600,400)
#LINE EDIT QCOMPLETER
self.label = QLineEdit(self)
self.label.setGeometry(100,100,300,30)
self.label.setStyleSheet("color: red;"
"font: bold 15pt 'Arial';")
self.t = ["Hello","hi","Hey"]
self.label.setCompleter(QCompleter(self.t, self))
#BUTTON
self.buton = QPushButton(self)
self.buton.setText("Click")
self.buton.setGeometry(200,140,90,50)
self.buton.clicked.connect(self.hangiButon)
#SET LABEL
self.set_label = QLabel(self)
self.set_label.setGeometry(100,300,900,100)
self.set_label.setStyleSheet("color: green;"
"font: bold 18pt 'Times New Roman';")
self.show()
def hangiButon(self):
print(self.label.text(), self.t.index(self.label.text())+1)
self.set_label.setText("Pressed to --> {}.".format(self.label.text().rstrip()))
def mousePressEvent(self, event):
self.oldPos = event.globalPos()
def mouseMoveEvent(self, event):
delta = QPoint (event.globalPos() - self.oldPos)
self.move(self.x() + delta.x(), self.y() + delta.y())
self.oldPos = event.globalPos()
app = QApplication(sys.argv)
app.setStyleSheet("QMainWindow{background-color: rgb(30,30,30);border: 2px solid rgb(20,20,20)}")
ex = cssden()
sys.exit(app.exec_())
So if I press h I want to see all of the words, not only hi and I want to change that h immediately. But couldn't figure out how.
The QCompleter widget has a setCaseSensitivity property that takes a QtCore.Qt.CaseSensitive / QtCore.Qt.CaseInsensitive or simply a 1 or 0 (docs).
The Qt documentaion says that "The default is Qt::CaseSensitive."
Changing the property to case-insensitive matching:
self.t = ["Hello","hi","Hey"]
my_completer = QCompleter(self.t, self)
my_completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
# my_completer.setCaseSensitivity(0)
self.label.setCompleter(my_completer)
To change the user input to uppercase you could add a method that changes the text:
def to_upper(self, txt):
self.label.setText(txt.upper())
which can then be connected to events such as self.label.textChanged:
self.label.textChanged.connect(self.to_upper)
Putting it together:
from PyQt5.QtWidgets import QApplication,QPushButton,QMainWindow,QLabel,QLineEdit,QCompleter
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtCore import QPoint
import sys
class cssden(QMainWindow):
def __init__(self):
super().__init__()
self.mwidget = QMainWindow(self)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
#size
self.setFixedSize(600,400)
#LINE EDIT QCOMPLETER
self.label = QLineEdit(self)
self.label.setGeometry(100,100,300,30)
self.label.setStyleSheet("color: red;"
"font: bold 15pt 'Arial';")
self.label.textChanged.connect(self.to_upper)
self.t = ["Hello","hi","Hey"]
my_completer = QCompleter(self.t, self)
#my_completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
my_completer.setCaseSensitivity(0)
self.label.setCompleter(my_completer)
#BUTTON
self.buton = QPushButton(self)
self.buton.setText("Click")
self.buton.setGeometry(200,140,90,50)
self.buton.clicked.connect(self.hangiButon)
#SET LABEL
self.set_label = QLabel(self)
self.set_label.setGeometry(100,300,900,100)
self.set_label.setStyleSheet("color: green;"
"font: bold 18pt 'Times New Roman';")
self.show()
def to_upper(self, txt):
self.label.setText(txt.upper())
def hangiButon(self):
print(self.label.text(), self.t.index(self.label.text())+1)
self.set_label.setText("Pressed to --> {}.".format(self.label.text().rstrip()))
def mousePressEvent(self, event):
self.oldPos = event.globalPos()
def mouseMoveEvent(self, event):
delta = QPoint (event.globalPos() - self.oldPos)
self.move(self.x() + delta.x(), self.y() + delta.y())
self.oldPos = event.globalPos()
app = QApplication(sys.argv)
app.setStyleSheet("QMainWindow{background-color: rgb(30,30,30);border: 2px solid rgb(20,20,20)}")
ex = cssden()
sys.exit(app.exec_())