I have a QTabWidget and add a set label to his upper right corner. When I set the width and height of the label, its border crosses the 'a' tab I added. I want to set the width and height of lalel. Do not cross the 'a' tab I added, how should I set
from PyQt4.QtCore import Qt
from PyQt4.QtGui import QTabWidget, QLabel
import sys
from PyQt4 import QtGui
class Setting(QLabel):
def __init__(self):
super(Setting, self).__init__()
self.setText('setting')
self.setStyleSheet("""*{border-width: 1px;
border-style: solid;
border-color: red;}""")
self.setFixedSize(30, 40)
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def create_tab(self):
self.tab = QTabWidget()
self.tab.addTab(QLabel('a'), 'a')
self.tab.setCornerWidget(Setting(), Qt.TopRightCorner)
def initUI(self):
self.create_tab()
h = QtGui.QHBoxLayout()
self.setLayout(h)
h.addWidget(self.tab)
self.setGeometry(100, 100, 500, 500)
self.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
If you remove the setFixedSize() from your label you can control the size and position through a stylesheet on the QTabWidget by targetting ::right-corner.
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def create_tab(self):
self.tab = QTabWidget()
self.tab.setStyleSheet('''
QTabWidget::right-corner {
width: 60px;
height: 25px;
subcontrol-position: left bottom;
}''')
self.tab.addTab(QLabel('a'), 'a')
self.tab.setCornerWidget(Setting(), Qt.TopRightCorner)
Instead of subcontrol-position you can also use top, bottom, left and right with pixel values to shift the control around.
Related
i'm trying to do a simple GUI for a python script that convert some text into a specific format but buttons doesn't show up in the window.
I first create the button class
class Button(QPushButton):
def __init__(self, btn_name=None):
super().__init__()
self.button = QPushButton(btn_name)
self.button.setCursor(
QCursor(QtCore.Qt.CursorShape.PointingHandCursor))
self.button.setStyleSheet(
"""*{border: 4px solid 'green';
border-radius: 45px;
font-size: 35px;
color: 'white';
padding: 25px 0;
margin: 100px, 200px}
*:hover{background: 'green'}
*:pressed{background: 'lightgreen'}"""
)
Then create the window class like this
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.window = QWidget()
self.window.resize(500, 500)
self.window.setWindowTitle("Pantuflis Software")
self.window.setFixedWidth(1000)
self.window.setStyleSheet("background: 'black';")
self.grid = QGridLayout()
self.window.setLayout(self.grid)
self.button = Button("Play")
self.grid.addWidget(self.button)
self.window.show()
Finally add the rest
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec())
But the button doesn't show up, only the main window does. I also tried the same but without creataing the button from my own class and works. Must be something wrong in the button class but i can't see what is.
If you are going to implement inherence then you have to apply the changes to the class. In your case it has a class that inherits from QPushButton but where you create the custom button which is not necessary, the same with the main window. My recommendation is that the OP should review his notes about inheritance.
import sys
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QCursor
from PyQt6.QtWidgets import QApplication, QGridLayout, QPushButton, QWidget
class Button(QPushButton):
def __init__(self, btn_name=""):
super().__init__(btn_name)
self.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
self.setStyleSheet(
"""*{border: 4px solid 'green';
border-radius: 45px;
font-size: 35px;
color: 'white';
padding: 25px 0;
margin: 100px, 200px}
*:hover{background: 'green'}
*:pressed{background: 'lightgreen'}"""
)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.resize(500, 500)
self.setWindowTitle("Pantuflis Software")
self.setFixedWidth(1000)
self.setStyleSheet("background: 'black';")
self.grid = QGridLayout(self)
self.button = Button("Play")
self.grid.addWidget(self.button)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
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 am using PyQt5 to create an application. The application has a MainWindow with several widgets. One of the widgets is a QLabel object that displays a video. I want to track the cursor and display the cursor coordinates as I mouse over the video when I check a radio button.
I created a MouseTracking class that I’m passing the QLabel object into as window. I have verified that the passed into the class by printing its geometry. But I’m somehow not associating the mouse tracking to window. Here is the code for the MouseTracking class. What am I doing wrong?
class MouseTracker(QLabel):
def __init__(self, window):
super().__init__(window)
self.window = window
self.window.setMouseTracking(True)
self.initUI()
def initUI(self):
self.label = QLabel(self)
self.label.setAlignment(Qt.AlignCenter)
self.label.setStyleSheet('background-color: white; border: 1px solid black')
self.show()
def mouseMoveEvent(self, event):
x = event.x()
y = event.y()
print("X, Y = ", x, y)
self.label.setGeometry(x+30, y-15, 90, 40)
self.label.setText('(%d, %d)' % (x, y))
In your code you have enabled the mouseTracking property of the "window" but you are monitoring the mouseMoveEvent method of the MouseTracker which is incorrect. If you want to track the events of a widget without overriding any method then you must use an event filter.
In the following example I try to implement your application based on your description, for example the green QLabel represents the QLabel that the video shows. Considering the above, the solution is as follows:
from PyQt5 import QtCore, QtGui, QtWidgets
class MouseTracker(QtCore.QObject):
positionChanged = QtCore.pyqtSignal(QtCore.QPoint)
def __init__(self, widget):
super().__init__(widget)
self._widget = widget
self.widget.setMouseTracking(True)
self.widget.installEventFilter(self)
#property
def widget(self):
return self._widget
def eventFilter(self, o, e):
if o is self.widget and e.type() == QtCore.QEvent.MouseMove:
self.positionChanged.emit(e.pos())
return super().eventFilter(o, e)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
self.video_label = QtWidgets.QLabel()
self.video_label.setStyleSheet("background-color: green; border: 1px solid black")
tracker = MouseTracker(self.video_label)
tracker.positionChanged.connect(self.on_positionChanged)
lay = QtWidgets.QVBoxLayout(central_widget)
lay.addWidget(self.video_label)
lay.addWidget(QtWidgets.QLabel())
self.resize(640, 480)
self.label_position = QtWidgets.QLabel(
self.video_label, alignment=QtCore.Qt.AlignCenter
)
self.label_position.setStyleSheet('background-color: white; border: 1px solid black')
#QtCore.pyqtSlot(QtCore.QPoint)
def on_positionChanged(self, pos):
delta = QtCore.QPoint(30, -15)
self.label_position.show()
self.label_position.move(pos + delta)
self.label_position.setText("(%d, %d)" % (pos.x(), pos.y()))
self.label_position.adjustSize()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
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()
Here is the code:
#!/usr/bin/env python3
import sys, time
from PySide import QtCore, QtGui
import base64
# Usage: Toast('Message')
class Toast(QtGui.QDialog):
def __init__(self, title, msg, duration=2):
QtGui.QDialog.__init__(self)
self.duration = duration
self.title_label = QtGui.QLabel(title)
self.title_label.setAlignment(QtCore.Qt.AlignLeft)
self.msg_label = QtGui.QLabel(msg)
self.icon_button = QLabelButton()
img_b64 = "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAITgAACE4BjDEA7AAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABJdEVYdENvcHlyaWdodABQdWJsaWMgRG9tYWluIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL3B1YmxpY2RvbWFpbi9Zw/7KAAAB2ElEQVRIibWVPW/TUBiFz7mJTBFSGgnUqmABRgpMUYi53pCK1IWxUxd2BgYk/goDAzuq+AFILEhIZUuq/ACPrYRKGSJPdHkPQx3UOK7tJOKd7Guf57nXH++lJFRVr9e70el03pLcBnAnH/4t6SzLsvdpml5U5duVdABhGDLLsj6AjSvD9wFshWHIujzrVgBcrqLb7b6U9AoASH6aTqdf62YPAK6WDiBN0wszO52dm9lpEzhQs4LhcNhzzj13zj2TtDUXJH+Z2bGZ/ZhMJulSApL03r+WtNdoluS38Xj8USWw0kcUx/F+UzgASNqL43i/7NqCwHu/A+CgKfxKHeTZagGAPsnWsvQ8028ieLIsvCq7IJD0eFV6WXZO4L3fzFvCSkVy23u/ea2A5KNV4dcx5gRm9nBdQZFRfAcP1hUUGXMC59zagiLjn2AwGNwCsPCjrFA7OWteEATBrqRG3bWqJLkgCHZn523gsrnFcdwi+YXkrGEJAMxMs+OSonNutukwF9DMWiQpSUyS5Kmku+vOvKzM7KxtZu8A3PwfAgB/2iQ/m9m9qrtIxgBuF4bPJY1qBD8b7clJkryQ9KYg/TAajb7XZRt9NVEUHUk6BHAC4ETSYRRFR02yfwEMBLRPQVtfqgAAAABJRU5ErkJggg=="
pixmap = QtGui.QPixmap()
pixmap.loadFromData(base64.b64decode(img_b64))
self.icon_button.setPixmap(pixmap)
self.icon_button.resize(20, 20)
self.connect(self.icon_button, QtCore.SIGNAL("clicked()"), self.close)
title_layout = QtGui.QVBoxLayout()
title_layout.addWidget(self.title_label)
title_layout.addWidget(self.msg_label)
layout = QtGui.QHBoxLayout()
layout.addWidget(self.icon_button)
layout.addLayout(title_layout)
self.setGeometry(0, 0, 200, 70)
self.setLayout(layout)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
# self.setStyleSheet("border: 1px solid red; border-radius: 5px;")
self.toastThread = ToastThread(self.duration)
self.toastThread.finished.connect(self.close)
self.toastThread.start()
class ToastThread(QtCore.QThread):
def __init__(self, n_seconds):
QtCore.QThread.__init__(self)
self.n_seconds = n_seconds
def run(self):
time.sleep(self.n_seconds)
class QLabelButton(QtGui.QLabel):
def __init(self, parent):
QLabel.__init__(self, parent)
def mouseReleaseEvent(self, ev):
self.emit(QtCore.SIGNAL('clicked()'))
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
program = Toast("hi", "there", 10)
program.show()
sys.exit(app.exec_())
Apparent the image label on the left is taking too much space. How can I fix this?
A horizontal layout will give each widget an equal amount of space by default, but you can adjust the ratio like this:
layout.addWidget(self.icon_button, 1)
layout.addLayout(title_layout, 3)
So that gives the title three times as much space as the icon.
This should work, just add:
self.icon_button.setFixedWidth(30)
by default it seperates the two widgets with equal width (=100)