cannot expand the progress bar to the full width of status bar - qt

I want the progress bar to expand to the full width of status bar,but why there is a gap there?
PS. can I add some text on the progress bar,there is no function like setText(), how can I do this ?
Is there a widget there or something else ?
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.resize(800, 600)
# self.lb=QLabel('finding resource ')
self.pb = QProgressBar()
self.pb.setRange(0, 0)
# self.pb.setTextVisible(False)
# self.statusBar().addPermanentWidget(self.lb)
self.statusBar().setSizeGripEnabled(False)
# print(self.statusBar().layout() )
self.statusBar().setStyleSheet("QStatusBar::item {border: none;}")
self.statusBar().addPermanentWidget(self.pb, 1)
if __name__ == "__main__":
app = QApplication(sys.argv)
ui = MainWindow()
ui.show()
sys.exit(app.exec_())

just set
self.pb.setTextVisible(False)

I think this solves your problem.
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.pb = QProgressBar()
# To make the text visible, you must not setRange(0, 0) and
# you must setValue(something valid). Otherwise, the text is
# hidden.
#
# In the default Windows style, the blank space to the right
# of the progress bar is room for this text. Calling
# setTextVisible(False) removes this space. Other styles will
# place the text in the middle of the progress bar.
#
# Unfortunately, I don't see any (simply) way to display a
# spinning progres bar AND text at the same time.
self.pb.setRange(0, 9)
self.pb.setValue(1)
self.pb.setFormat('finding resource...')
self.statusBar().setSizeGripEnabled(False)
self.statusBar().addPermanentWidget(self.pb, 1)
if __name__ == "__main__":
app = QApplication(sys.argv)
ui = MainWindow()
ui.show()
sys.exit(app.exec_())

Related

I can't see QLabel and QLineEdit widgets in my QMainWindow in Python2

I wrote this code and I don't understand why widgets QLabel and QLineEdit don't show up? Do I have to put them in another class? It's Python2.7 and PySide.
This is how a window looks like when I run the code:
#!/usr/bin/env python
# coding: utf-8
import sys
import crypt
from PySide import QtGui
class MyApp(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MyApp, self).__init__(parent)
self.initui()
def initui(self):
# main window size, title and icon
self.setMinimumSize(500, 350)
self.setWindowTitle("Calculate a password hash in Linux")
# lines for entering data
self.saltLabel = QtGui.QLabel("Salt:")
self.saltLine = QtGui.QLineEdit()
self.saltLine.setPlaceholderText("e.g. $6$xxxxxxxx")
# set layout
grid = QtGui.QGridLayout()
grid.addWidget(self.saltLabel, 0, 0)
grid.addWidget(self.saltLine, 1, 0)
self.setLayout(grid)
# show a widget
self.show()
def main():
app = QtGui.QApplication(sys.argv)
instance = MyApp()
instance.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
How about using a QWidget as centralWidget
widget = QWidget()
widget.setLayout(grid)
#add your widgets and...
self.setCentralWidget(widget)
and you don't need to call show() since you do in your __main__
It's up to the owner but i would recommend sublassing a QWidget and leave your QMainWindow instance as concise as possible. An implementation could be:
class MyWidget(QtGui.QWidget):
def __init__(self, *args):
QtGui.QWidget.__init__(self, *args)
grid = QtGui.QGridLayout()
#and so on...
and use this as widget in your QMainWindow instance. This increases readability and maintainability and reusability a lot :)

Restrict item in PyQt4‏ using itemChange()

I tried using the Qt documentation example to restrict the rectangle to the area of the scene but it still fails, someone has an alternative to do this?
My code, the QGraphicsView instance was created in Qt Desginer:
# -*- coding: utf-8 -*-
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
from screen import *
class MovableItem(QGraphicsRectItem):
def __init__(self, rectang, *args, **kwargs):
QGraphicsRectItem.__init__(self, rectang, *args, **kwargs)
self.setFlags(QGraphicsItem.ItemIsMovable |
QGraphicsItem.ItemSendsGeometryChanges)
self.pen = QPen(Qt.darkMagenta)
self.pen.setWidth(4)
self.setPen(self.pen)
def itemChange(self, change, value):
if change == QGraphicsItem.ItemPositionChange and self.scene():
# value is the new position.
self.newPos = value.toPointF()
self.rect = self.scene().sceneRect()
if not(self.rect.contains(self.newPos)):
# Keep the item inside the scene rect.
self.newPos.setX(min(self.rect.right(), max(self.newPos.x(), self.rect.left())))
self.newPos.setY(min(self.rect.bottom(), max(self.newPos.y(), self.rect.top())))
return self.newPos
return QGraphicsRectItem.itemChange(self, change, value)
class Main(QWidget, Ui_Form):
def __init__(self, parent=None):
super(Main, self).__init__(parent)
self.setupUi(self)
self.scene = QGraphicsScene()
self.cena.setScene(self.scene)
self.scene.addPixmap(QPixmap("01.png"))
self. graph = MovableItem(2, 2, 300, 150)
self.scene.addItem(self.graph)
def showEvent(self, event):
self.cena.fitInView(self.scene.sceneRect(), Qt.IgnoreAspectRatio)
app = QApplication(sys.argv)
window = Main()
window.show()
sys.exit(app.exec_())
First:
Use setSceneRect() in your main Main(), to set the size of the scene.
Second:
Actually the example of the documentation is wrong, therefore, to adjust the rectangle to the scene, delete this if and subtract, in min, the parameters right and bottom by the rectangle dimensions right and bottom in setX and setY. Replace this part of your code:
if not(self.rect.contains(self.newPos)):
# Keep the item inside the scene rect.
self.newPos.setX(min(self.rect.right(), max(self.newPos.x(), self.rect.left())))
self.newPos.setY(min(self.rect.bottom(), max(self.newPos.y(), self.rect.top())))
return self.newPos
For:
self.newPos.setX(min(self.rect.right()-self.boundingRect().right(), max(self.newPos.x(), self.rect.left())))
self.newPos.setY(min(self.rect.bottom()-self.boundingRect().bottom(), max(self.newPos.y(), self.rect.top())))
return self.newPos

pyqtgraph custom tick labels potential bug

I'm using PyQtGraph and embedding a graph into a Qt program. I've added axisItems to the PlotWidget's constructor. It seems to do something a bit weird; I get some off line with 0___1 in the top right-hand corner. Does anyone know what is causing this and/or how to get rid of it?
I've attached a picture showing this and my code to generate what's in the picture.
If I don't add the AxisItem to the constructor (hence not getting my custom tick labels), the issue doesn't occur.
import sys
import numpy as np
from PySide import QtCore, QtGui, QtUiTools, QtXml
from ui import *
import pyqtgraph as pg
class PlotWidgetBarGraph(pg.PlotWidget):
def __init__(self, **opts):
# Add custom tick strings.
xDict = {1.:'1', 2.:'2', 3.:'3', 4.:'4',
5.:'5', 6.:'6', 7.:'7', 8.:'8',
9.:'1/2', 10.:'1/3', 11.:'1/4',
12.:'2/3', 13.:'2/4', 14.:'3/4',
15.:'1/2/3', 16.:'2/3/4',
17:'1/2/3/4'}
xAxis = pg.AxisItem(orientation='bottom')
xAxis.setTicks([xDict.items(), []])
super().__init__(axisItems={'bottom': xAxis})
# Create and add bar graph.
bg = pg.BarGraphItem(**opts)
self.addItem(bg)
class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
splitter = QtGui.QSplitter(QtCore.Qt.Vertical)
x = np.arange(20)
y = np.abs(np.sin(x))+0.1
plot1 = PlotWidgetBarGraph(x=x, height=y, width=0.8, brush='b')
plot2 = PlotWidgetBarGraph(x=x, height=y, width=0.8, brush='b')
splitter.addWidget(plot1)
splitter.addWidget(plot2)
splitter.setStretchFactor(0, 1)
splitter.setStretchFactor(1, 2)
self.verticalLayout.addWidget(splitter)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())

QMovie setting filename second time wont work

I am setting the Initial Movie File like this:
self.movie = QMovie("dotGreenBlack.gif", QByteArray(), self)
At runtime, i want to change it by setting:
self.movie.setFileName("dotGreyStatic.gif")
But this leads to frame-freeze of the primarly set file "dotGreenBlack.gif"
Anything else i have to do to change the Gif-Animation on runtime?
Here is the fullcode:
from PyQt4 import QtCore, QtGui
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys
class ImagePlayer(QWidget):
def __init__(self, filename, title, parent=None):
QWidget.__init__(self, parent)
# Load the file into a QMovie
self.movie = QMovie(filename, QByteArray(), self)
size = self.movie.scaledSize()
self.setGeometry(200, 200, size.width(), size.height())
self.setWindowTitle(title)
self.movie_screen = QLabel()
# Make label fit the gif
self.movie_screen.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.movie_screen.setAlignment(Qt.AlignCenter)
# Create the layout
main_layout = QVBoxLayout()
main_layout.addWidget(self.movie_screen)
self.setLayout(main_layout)
# Add the QMovie object to the label
self.movie.setCacheMode(QMovie.CacheAll)
self.movie.setSpeed(100)
self.movie_screen.setMovie(self.movie)
self.movie.start()
self.movie.loopCount()
self.movie.setFileName("dotGreyStatic.gif")
self.movie_screen.setMovie(self.movie)
if __name__ == "__main__":
gif = "dotGreenBlack.gif"
app = QApplication(sys.argv)
app.setStyleSheet("QWidget { background-color: black }")
player = ImagePlayer(gif, "was")
player.show()
sys.exit(app.exec_())
Gif Icons used in this Example:
You just need to stop and restart the movie:
self.movie.stop()
self.movie.setFileName("dotGreyStatic.gif")
self.movie.start()

PySide crashing when replacing rows in QFormLayout

Using the following code example PySide segfaults when pushing "Add", "Add", "Remove", "Add" and due to some other sequences of interaction.
Python: 2.7.6
PySide: 1.2.1
QtCore: 4.8.5
Code:
from PySide.QtGui import *
from PySide.QtCore import *
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setObjectName('MainWindow')
self.baseLayout = QWidget(self)
self.v_layout = QVBoxLayout(self.baseLayout)
self.setCentralWidget(self.baseLayout)
self.form_layout = QFormLayout(self.baseLayout)
self.v_layout.addLayout(self.form_layout)
self.button_add = QPushButton(self.baseLayout)
self.button_add.setText("Add")
self.v_layout.addWidget(self.button_add)
self.button_del = QPushButton(self.baseLayout)
self.button_del.setText("Remove")
self.v_layout.addWidget(self.button_del)
self.button_add.clicked.connect(self.add)
self.button_del.clicked.connect(self.remove)
self.fields = []
def add_item(self):
layout = QHBoxLayout(self.parent())
line = QLineEdit(self.parent())
slider = QSlider(self.parent())
layout.addWidget(line)
layout.addWidget(slider)
self.fields.append((layout, line, slider))
self.form_layout.addRow("Test", layout)
def add(self):
for i in range(15):
self.add_item()
def remove(self):
for (layout, line, slider) in self.fields:
line.deleteLater()
slider.deleteLater()
while self.form_layout.itemAt(0):
child = self.form_layout.takeAt(0)
if child.widget():
child.widget().deleteLater()
self.form_layout.update()
self.fields = []
def main():
import sys
app = QApplication(sys.argv)
frame = MainWindow()
frame.show()
app.exec_()
if __name__ == '__main__':
main()
Is this the correct way of adding compound widgets (in this case a QLineEdit and a QSlider within a QVBoxLayout) to a form layout? What am I doing wrong?
The correct way of adding "compound widgets" to a QFormLayout is to create a QWidget that will be the parent to that layout.
add_item() should rather look something like this:
def add_item(self):
widget = QWidget(self.parent())
layout = QHBoxLayout(widget)
line = QLineEdit(widget)
slider = QSlider(widget)
layout.addWidget(line)
layout.addWidget(slider)
self.fields.append((layout, widget, line, slider))
self.form_layout.addRow("Test", widget)
(And the widget also has to be removed when deleting the fields).
I think you are not creating the layouts in the right way, for example you are trying to set the layout of base_layout two times. Also you can check for count() on a QLayout to see if it has children:
from PySide.QtGui import *
from PySide.QtCore import *
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.baseLayout = QWidget(self)
self.v_layout = QVBoxLayout(self.baseLayout)
self.setCentralWidget(self.baseLayout)
self.form_layout = QFormLayout()
self.v_layout.addLayout(self.form_layout)
self.button_add = QPushButton()
self.button_add.setText("Add")
self.v_layout.addWidget(self.button_add)
self.button_del = QPushButton()
self.button_del.setText("Remove")
self.v_layout.addWidget(self.button_del)
self.button_add.clicked.connect(self.add)
self.button_del.clicked.connect(self.remove)
self.fields = []
def add_item(self):
layout = QHBoxLayout()
line = QLineEdit()
slider = QSlider()
layout.addWidget(line)
layout.addWidget(slider)
self.fields.append((layout, line, slider))
self.form_layout.addRow("Test", layout)
def add(self):
for i in range(15):
self.add_item()
def remove(self):
while self.form_layout.count() > 0:
child = self.form_layout.takeAt(0)
widget = child.widget()
if widget:
widget.deleteLater()
self.form_layout.update()
self.fields = []
def main():
import sys
app = QApplication(sys.argv)
frame = MainWindow()
frame.show()
app.exec_()
if __name__ == '__main__':
main()

Resources