pyqt5 - items in QHBoxLayout overlap? - python

I've seen several similar questions on items overlapping in (py)Qt, but I cannot for the life of me figure out why I get these overlapping elements (label and slider) inside a QHBoxLayout:
... with this code:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class Example(QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
#pyqtSlot()
def onclick(self):
print("AAA")
# QApplication.processEvents()
setstr = ""
if self.btn_yrange.isChecked(): setstr = "yrange auto ON"
else: setstr = "yrange auto OFF"
self.btn_yrange.setText(setstr)
#self.btn_yrange.adjustSize()
def initUI(self):
self.col = QColor(0, 0, 0)
self.slider_hbox = QHBoxLayout()
self.btn_yrange = QPushButton('yrange auto OFF', self)
self.btn_yrange.setCheckable(True)
self.btn_yrange.clicked.connect(self.onclick)
self.slider_yrange = QSlider(Qt.Horizontal, self)
self.slider_yrange.setFocusPolicy(Qt.StrongFocus)
self.slider_yrange.setTickPosition(QSlider.TicksBothSides)
self.slider_yrange.setTickInterval(10)
self.slider_yrange.setSingleStep(1)
self.slider_hbox.addStretch(1)
self.slider_hbox.addWidget(self.btn_yrange, Qt.AlignRight)
self.slider_hbox.addStretch(1)
self.slider_hbox.addSpacing(10)
self.slider_hbox.addWidget(self.slider_yrange)
self.slider_hbox.addStretch(1)
self.setGeometry(300, 300, 280, 170)
self.setWindowTitle('Toggle button')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
How do I force the label and the slider to be side-by-side?

Ok, got it - I saw http://zetcode.com/gui/pyqt5/layout/ - and realized, I had forgotten to add self.setLayout(self.slider_hbox) before self.setGeometry. So, now I get this:
... with this code:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class Example(QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
#pyqtSlot()
def onclick(self):
print("AAA")
# QApplication.processEvents()
setstr = ""
if self.btn_yrange.isChecked(): setstr = "yrange auto ON"
else: setstr = "yrange auto OFF"
self.btn_yrange.setText(setstr)
#self.btn_yrange.adjustSize()
def initUI(self):
self.col = QColor(0, 0, 0)
self.slider_hbox = QHBoxLayout()
self.btn_yrange = QPushButton('yrange auto OFF', self)
self.btn_yrange.setCheckable(True)
#btn_yrange.move(10, 10)
#self.btn_yrange.clicked.connect(self.onclick)
self.btn_yrange.clicked.connect(self.onclick)
self.slider_yrange = QSlider(Qt.Horizontal, self)
self.slider_yrange.setFocusPolicy(Qt.StrongFocus)
self.slider_yrange.setTickPosition(QSlider.TicksBothSides)
self.slider_yrange.setTickInterval(10)
self.slider_yrange.setSingleStep(1)
#self.slider_hbox.addStretch(1)
self.slider_hbox.addWidget(self.btn_yrange, Qt.AlignRight)
#self.slider_hbox.addStretch(1)
self.slider_hbox.addSpacing(10)
self.slider_hbox.addWidget(self.slider_yrange)
#self.slider_hbox.addStretch(1)
self.setLayout(self.slider_hbox)
self.setGeometry(300, 300, 280, 170)
self.setWindowTitle('Toggle button')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())

Related

KeyPressEvent() doesn't work with label when I add PushButtons

`
from PyQt5.QtCore import Qt
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtWidgets import QLabel, QPushButton
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 1000, 1000)
self.setWindowTitle('Example')
self.label_backround = QLabel(self)
self.label_backround.move(100, 100)
self.label_backround.resize(800, 800)
self.label = QLabel(self)
self.label.setText("xxxxx")
self.label.move(340, 340)
self.Button1 = QPushButton('1', self)
self.Button1.move(580, 250)
self.Button2 = QPushButton('2', self)
self.Button2.move(590, 560)
self.Button3 = QPushButton('3', self)
self.Button3.move(210, 660)
def keyPressEvent(self, event):
x = self.label.x()
y = self.label.y()
if event.key() == Qt.Key_Left:
self.label.move(x - 15, y)
elif event.key() == Qt.Key_Up:
self.label.move(x, y - 15)
elif event.key() == Qt.Key_Right:
self.label.move(x + 15, y)
elif event.key() == Qt.Key_Down:
self.label.move(x, y + 15)
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
`I have a window on which is a label that should move when I press the up, down, right and left buttons on keyboard. It works, but when I add some PushButtons the label doesn't move.
Сan anyone know what this is about?
The widget that receives the keypress event only the widget that has the focus, and by default many widgets like the QPushButtons take the focus unlike a QWidget. In this case you should not use keyPressEvent but a QShorcut that allows you to capture keyboard events independently of the widgets (obviously you can set limitations through context). Considering the above, the solution is:
import sys
from PyQt5.QtCore import QPoint, Qt
from PyQt5.QtGui import QKeySequence
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow, QPushButton, QShortcut
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 1000, 1000)
self.setWindowTitle("Example")
self.label_backround = QLabel(self)
self.label_backround.move(100, 100)
self.label_backround.resize(800, 800)
self.label = QLabel(self)
self.label.setText("xxxxx")
self.label.move(340, 340)
self.Button1 = QPushButton("1", self)
self.Button1.move(580, 250)
self.Button2 = QPushButton("2", self)
self.Button2.move(590, 560)
self.Button3 = QPushButton("3", self)
self.Button3.move(210, 660)
QShortcut(QKeySequence(Qt.Key_Left), self, activated=self.move_left)
QShortcut(QKeySequence(Qt.Key_Up), self, activated=self.move_up)
QShortcut(QKeySequence(Qt.Key_Right), self, activated=self.move_right)
QShortcut(QKeySequence(Qt.Key_Down), self, activated=self.move_down)
def move_left(self):
self.label.move(self.label.pos() + QPoint(-15, 0))
def move_up(self):
self.label.move(self.label.pos() + QPoint(0, -15))
def move_right(self):
self.label.move(self.label.pos() + QPoint(15, 0))
def move_down(self):
self.label.move(self.label.pos() + QPoint(0, 15))
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())

how to display the range values in slider

Here is my code, i want to display the minimum and maximum range values for slider.I tried many ways but i didn't get anything.Can anyone please help me how to display the slider as shown in the bellow image.
Given bellow is my code:
from pyface.qt import QtGui, QtCore
import sys
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.vbox = QtGui.QVBoxLayout()
self.label3 = QtGui.QLabel()
self.slider = QtGui.QSlider()
self.slider.setMinimum(0)
self.slider.setMaximum(100)
self.slider.setTickPosition(QtGui.QSlider.TicksLeft)
self.slider.setOrientation(QtCore.Qt.Horizontal)
self.slider.setOrientation(QtCore.Qt.Horizontal)
self.vbox.addWidget(self.slider,QtCore.Qt.AlignBottom)
self.vbox.addWidget(self.label3)
self.setLayout(self.vbox)
self.setGeometry(300, 300, 300, 150)
self.slider.valueChanged.connect(self.valuechange)
self.show()
def valuechange(self):
txt = str(self.slider.value())
self.label3.setText(txt)
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
You can use 2 QLabels with QHBoxLayout and QVBoxLayout:
from pyface.qt import QtGui, QtCore
import sys
class Slider(QtGui.QSlider):
minimumChanged = QtCore.Signal(int)
maximumChanged = QtCore.Signal(int)
def setMinimum(self, minimum):
self.minimumChanged.emit(minimum)
super(Slider, self).setMinimum(minimum)
def setMaximum(self, maximum):
self.maximumChanged.emit(maximum)
super(Slider, self).setMaximum(maximum)
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.label = QtGui.QLabel(alignment=QtCore.Qt.AlignCenter)
self.slider = Slider(tickPosition=QtGui.QSlider.TicksLeft,
orientation=QtCore.Qt.Horizontal)
slider_vbox = QtGui.QVBoxLayout()
slider_hbox = QtGui.QHBoxLayout()
slider_hbox.setContentsMargins(0, 0, 0, 0)
slider_vbox.setContentsMargins(0, 0, 0, 0)
slider_vbox.setSpacing(0)
label_minimum = QtGui.QLabel(alignment=QtCore.Qt.AlignLeft)
self.slider.minimumChanged.connect(label_minimum.setNum)
label_maximum = QtGui.QLabel(alignment=QtCore.Qt.AlignRight)
self.slider.maximumChanged.connect(label_maximum.setNum)
slider_vbox.addWidget(self.slider)
slider_vbox.addLayout(slider_hbox)
slider_hbox.addWidget(label_minimum, QtCore.Qt.AlignLeft)
slider_hbox.addWidget(label_maximum, QtCore.Qt.AlignRight)
slider_vbox.addStretch()
self.slider.setMinimum(0)
self.slider.setMaximum(100)
vbox = QtGui.QVBoxLayout(self)
vbox.addLayout(slider_vbox)
vbox.addWidget(self.label)
self.setGeometry(300, 300, 300, 150)
self.slider.valueChanged.connect(self.label.setNum)
self.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

PySide/PyQT5: How to emit signals from a QGraphicsItem?

I want to emit a signal from a QGraphicsItem when it is doubled-clicked, in order to change a widget in the main window. The graphics-scene/-item does not provide an emit() method, but I was just wondering if there is an alternate way to do this. The code below has a function within a QGraphicsView class that will print to the terminal when an item is double-clicked. How can I make that into a slot/signal instead (if QGraphicsItem does not support signal/slots)?
import sys
from PySide.QtCore import *
from PySide.QtGui import *
class MyFrame(QGraphicsView):
def __init__( self, parent = None ):
super(MyFrame, self).__init__(parent)
scene = QGraphicsScene()
self.setScene(scene)
self.setFixedSize(500, 500)
pen = QPen(QColor(Qt.green))
brush = QBrush(pen.color().darker(150))
item = scene.addEllipse(0, 0, 45, 45, pen, brush)
item.setPos(0,0)
def mouseDoubleClickEvent(self, event):
print("Circle Clicked!")
# this double click event prints to terminal but how to setup
# signal/slot to update the QWidget QLabel text instead?
class Example(QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
hbox = QHBoxLayout(self)
top = QLabel("Double Click Green Circle (Howto change this QWidget Label with signals?)")
bottom = MyFrame()
splitter = QSplitter(Qt.Vertical)
splitter.addWidget(top)
splitter.addWidget(bottom)
hbox.addWidget(splitter)
self.setLayout(hbox)
self.setGeometry(0, 0, 500, 600)
self.show()
def main():
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Below is a simple example showing one way to emit signals from a graphics-item. This defines a custom signal on a subclass of QGraphicsScene and then uses the scene() method of graphics-items to emit it:
import sys
from PySide import QtCore, QtGui
class GraphicsScene(QtGui.QGraphicsScene):
itemDoubleClicked = QtCore.Signal(object)
class GraphicsRectangle(QtGui.QGraphicsRectItem):
def mouseDoubleClickEvent(self, event):
self.scene().itemDoubleClicked.emit(self)
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
self.view = QtGui.QGraphicsView()
self.scene = GraphicsScene(self)
self.view.setScene(self.scene)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.view)
for i in range(1, 4):
self.scene.addItem(GraphicsRectangle(50 * i, 50 * i, 20, 20))
self.scene.itemDoubleClicked.connect(self.handleItemDoubleClicked)
def handleItemDoubleClicked(self, item):
print(item.boundingRect())
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(600, 100, 300, 200)
window.show()
sys.exit(app.exec_())
UPDATE:
Below is a an example based on the code in your question. The basic idea is the same: define a custom signal on an available QObject (the graphics-view in this case), and use that to emit the double-click notification.
import sys
from PySide.QtCore import *
from PySide.QtGui import *
class MyFrame(QGraphicsView):
itemDoubleClicked = Signal(object)
def __init__(self, parent=None):
super(MyFrame, self).__init__(parent)
scene = QGraphicsScene()
self.setScene(scene)
self.setFixedSize(500, 500)
for i, color in enumerate('red blue green'.split()):
pen = QPen(QColor(color))
brush = QBrush(pen.color().darker(150))
item = scene.addEllipse(i * 50, i * 50, 45, 45, pen, brush)
item.setData(0, color.upper())
def mouseDoubleClickEvent(self, event):
item = self.itemAt(event.pos())
if item is not None:
self.itemDoubleClicked.emit(item)
class Example(QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
hbox = QHBoxLayout(self)
top = QLabel('Double Click a Circle')
bottom = MyFrame()
bottom.itemDoubleClicked.connect(
lambda item, top=top:
top.setText('Double Clicked: %s' % item.data(0)))
splitter = QSplitter(Qt.Vertical)
splitter.addWidget(top)
splitter.addWidget(bottom)
hbox.addWidget(splitter)
self.setLayout(hbox)
self.setGeometry(0, 0, 500, 600)
self.show()
def main():
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

Python count How many Clicks are in a second

Would someone mind helping me with this? I'm trying to make a clicks per second test like this one on this website.
I've tried many different things, but I couldn't figure it out
Here are my imports
from PyQt4.QtCore import QSize
from PyQt4.QtGui import QApplication, QMainWindow, QPushButton, QWidget, QIcon, QLabel, QPainter, QPixmap
here is my code
class UICPS(QWidget): #||| CPS TAB |||
def __init__(self, parent=None):
super(UICPS, self).__init__(parent)
clicks = 0
self.Back = QPushButton("<- Back", self)
self.Back.resize(50,25)
self.Back.move(0, 425)
self.Clicked = QLabel(str(clicks), self)
self.Clicked.move(200, 200)
self.CPSBTN = QPushButton("Click Me!", self)
self.CPSBTN.resize(400, 175)
self.CPSBTN.move(0, 250)
if self.Clicked:
clicks +1
My Solution:
import sys
from PyQt4.QtCore import QTimer
from PyQt4.QtGui import QApplication, QLabel, QPushButton, QWidget
class UICPS(QWidget):
def __init__(self, parent=None):
super(UICPS, self).__init__(parent)
self.clicks = 0
self.Back = QPushButton("<- Back", self)
self.Back.resize(50, 25)
self.Back.move(0, 425)
self.ClickedLB = QLabel(str(self.clicks), self)
self.ClickedLB.resize(400, 20)
self.ClickedLB.move(200, 100)
self.ClickedLB2 = QLabel(str(self.clicks), self)
self.ClickedLB2.resize(400, 20)
self.ClickedLB2.move(200, 150)
self.ClickedLB3 = QLabel(str(self.clicks), self)
self.ClickedLB3.resize(400, 20)
self.ClickedLB3.move(200, 200)
self.CPSBTN = QPushButton("Click Me!", self)
self.CPSBTN.clicked.connect(self.Clicked)
self.CPSBTN.resize(400, 175)
self.CPSBTN.move(0, 250)
self.resize(400, 450)
self.starting = False
self.timer = QTimer(self)
self.timer.timeout.connect(self.updateClock)
self.counter = 0
self.isFist = True
def updateClock(self):
self.counter += 0.01
self.ClickedLB2.setText("%.2f s" % self.counter)
if self.counter >= 9.99:
self.starting = False
cps = self.clicks/10
self.ClickedLB3.setText("%.2f CPS" % cps)
self.timer.stop()
def Clicked(self):
if self.starting:
self.clicks += 1
self.ClickedLB.setText(str(self.clicks))
else:
if self.isFist:
self.timer.start(10)
self.starting = True
self.isFist = False
if __name__ == '__main__':
app = QApplication(sys.argv)
w = UICPS()
w.show()
sys.exit(app.exec_())
After clicked:
You have to assign function to button
from PyQt4 import QtGui
import sys
class MyWindow(QtGui.QWidget):
def __init__(self, parent=None):
super(MyWindow, self).__init__()
self.clicks = 0
self.vbox = QtGui.QVBoxLayout()
self.setLayout(self.vbox)
self.label = QtGui.QLabel(str(self.clicks), self)
self.vbox.addWidget(self.label)
self.button = QtGui.QPushButton("Click Me!", self)
self.vbox.addWidget(self.button)
# assign function to button
self.button.clicked.connect(self.on_click)
self.show()
def on_click(self):
self.clicks += 1
self.label.setText(str(self.clicks))
app = QtGui.QApplication(sys.argv)
win = MyWindow()
app.exec_()

force python pyside splitter to start window center

How can I force the splitter to be positioned in the center of the window at the start? As you can see in the code below it favors the right side because of the button being small. however I would like to have the splitter always appear in the middle of the window as shown in image two.
Current
Goal
import sys
from PySide import QtGui, QtCore
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
# formatting
self.resize(550, 400)
self.setWindowTitle("Cameras")
# widgets
self.ListA = QtGui.QTreeWidget()
self.ListB = QtGui.QTreeWidget()
self.Button = QtGui.QPushButton()
# layout Splitter
self.mainLayout = QtGui.QHBoxLayout(self)
self.mainLayout.setContentsMargins(5,5,5,5)
self.leftPanel = QtGui.QFrame(self)
# self.leftPanel.setFrameShape(QtGui.QFrame.StyledPanel)
self.leftPanelLayout = QtGui.QHBoxLayout(self.leftPanel)
self.leftPanelLayout.setContentsMargins(0,0,0,0)
self.leftPanelLayout.addWidget(self.ListA)
self.rightPanel = QtGui.QFrame(self)
# self.rightPanel.setFrameShape(QtGui.QFrame.StyledPanel)
self.rightPanelLayout = QtGui.QHBoxLayout(self.rightPanel)
self.rightPanelLayout.setContentsMargins(0,0,0,0)
self.rightPanelLayout.addWidget(self.Button)
self.splitter = QtGui.QSplitter(QtCore.Qt.Horizontal)
self.splitter.addWidget(self.leftPanel)
self.splitter.addWidget(self.rightPanel)
self.mainLayout.addWidget(self.splitter)
self.setGeometry(300, 300, 300, 200)
self.setWindowTitle('QtGui.QSplitter')
self.show()
def onChanged(self, text):
self.lbl.setText(text)
self.lbl.adjustSize()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Bam! got it.
import sys
from PySide import QtGui, QtCore
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
# formatting
self.resize(1000, 1000)
self.setWindowTitle("Cameras")
# widgets
self.ListA = QtGui.QTreeWidget()
self.ListB = QtGui.QTreeWidget()
self.Button = QtGui.QPushButton()
# layout Splitter
# QHBoxLayout
self.mainLayout = QtGui.QGridLayout(self)
self.mainLayout.setContentsMargins(5,5,5,5)
self.leftPanel = QtGui.QFrame(self)
# self.leftPanel.setFrameShape(QtGui.QFrame.StyledPanel)
self.leftPanelLayout = QtGui.QHBoxLayout(self.leftPanel)
self.leftPanelLayout.setContentsMargins(0,0,0,0)
self.leftPanelLayout.addWidget(self.ListA)
self.rightPanel = QtGui.QFrame(self)
# self.rightPanel.setFrameShape(QtGui.QFrame.StyledPanel)
self.rightPanelLayout = QtGui.QHBoxLayout(self.rightPanel)
self.rightPanelLayout.setContentsMargins(0,0,0,0)
self.rightPanelLayout.addWidget(self.Button)
self.splitter = QtGui.QSplitter(QtCore.Qt.Horizontal)
self.splitter.addWidget(self.leftPanel)
self.splitter.addWidget(self.rightPanel)
self.splitter.setCollapsible(0,False)
self.splitter.setCollapsible(1,False)
self.mainLayout.addWidget(self.splitter,0,0)
self.setWindowTitle('QtGui.QSplitter')
self.show()
self.set_panel_sizes(self.splitter)
def onChanged(self, text):
self.lbl.setText(text)
self.lbl.adjustSize()
def set_panel_sizes(self, ctrl):
width = ctrl.frameSize().width() / 2.0
ctrl.setSizes( [width,width] )
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

Categories

Resources