Widget opens for a second then automatically closes? - python

I haven been trying to make a simple widget appear when I click a certain button, but for some reason my widget keeps disappearing and I have no idea why. Below is the code that I have for the widget:
if button.pressed() == True:
box = messageBox(self.text)
box.show()
class messageBox(QtGui.QWidget):
def __init__(self, text):
self.message = text
super(messageBox, self).__init__()
self.initUI()
def initUI(self):
self.resize(250, 100)
self.move(300, 300)
self.label = QtGui.QLabel(self)
self.label.setText(self.message.toPlainText())
When the button is pressed, I just want to display a widget with all the information inside self.text but for some reason my widget keeps disappearing when I click the button. If anyone could help that would be highly appreciated! Thanks!

It disappears because it get's garbage collected. You create a box, but when your function finishes, the variable box is deleted and since nothing is pointing to the widget it gets garbage collected and disappears. You have to save a reference to the box and keep it somewhere. Example:
from PyQt4 import QtGui, QtCore
class messageBox(QtGui.QWidget):
def __init__(self, text):
super(messageBox, self).__init__()
self.message = text
self.initUI()
def initUI(self):
self.resize(250, 100)
self.move(300, 300)
self.label = QtGui.QLabel(self)
self.label.setText(self.message)
class MainWidget(QtGui.QWidget):
def __init__(self, text):
super(MainWidget, self).__init__()
button = QtGui.QPushButton('Push')
button.pressed.connect(self.on_button_pressed)
layout = QtGui.QVBoxLayout()
layout.addWidget(button)
self.setLayout(layout)
def on_button_pressed(self):
self.box = messageBox('foo')
self.box.show()
app = QtGui.QApplication([])
mw = MainWidget('test')
mw.show()
app.exec_()
Also you shouldn't check if button.pressed() you should connect it's pressed signal to a function that will be called whenever the button is pressed (but I assume that snippet was just a pseudo code).

Related

QLabel limiting text length on second calling setText() to the length of the first value

When setting a label in the init of a QWidget the text is shown properly, however on changing the text with the press of a button the text is not shown fully.
It is limited at the char length of the old string. How can this be solved?
Thanks in advance!
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
self.setGeometry(500, 500, 500, 420)
Button("Change it!", self).set_tool_tip("Change the label text").resize().move(0, 40).on_click(
self.change_label)
self.Label = QLabel(self)
self.Label.setText("I'm going to change and get bigger!")
self.Label.move(0, 65)
def change_label(self):
self.Label.setText("I'm bigger then I was before, unfortunately I'm not fully shown. Can you help me? :)")
You have to change size manually using self.Label.resize(width, height) in change_label. But you don't know what value use as width
Better use any layout manager and it will resize widget automatically.
Example with layout manager Vertical Boxes - QVBoxLayout
from PyQt5.QtWidgets import *
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
layout = QVBoxLayout()
self.setLayout(layout)
self.button = QPushButton("Change it!", self)
self.button.clicked.connect(self.change_label)
layout.addWidget(self.button)
self.label = QLabel(self)
self.label.setText("I'm going to change and get bigger!")
layout.addWidget(self.label)
def change_label(self):
self.label.setText("I'm bigger then I was before, unfortunately I'm not fully shown. Can you help me? :)")
app = QApplication([])
main = MainWindow()
main.show()
app.exec()

PyQt how to make a toolbar button appeared as pressed

I want to make a specific button in PyQt toolbar appeared as pressed(with blue background). Suppose when I hit the toolbar button I want it to be appeared as pressed
import sys
from PyQt4 import QtGui, QtCore
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class Window(QtGui.QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.setGeometry(50, 50, 700, 700)
self.setWindowTitle('Rich Text Editor')
self.statusBar = QStatusBar()
self.textEdit = QtGui.QTextEdit()
self.setCentralWidget(self.textEdit)
self.setStatusBar(self.statusBar)
self.home()
def home(self):
changeBoldActionTB = \
QtGui.QAction(QtGui.QIcon('bold-text-option.png'),
'Make the text bold', self)
changeBoldActionTB.triggered.connect(self.changeBold)
self.formatbar = QToolBar()
self.addToolBar(Qt.TopToolBarArea, self.formatbar)
self.formatbar.addAction(changeBoldActionTB)
self.show()
def changeBold(self):
pass
#I think this does't matter
def run():
app = QtGui.QApplication(sys.argv)
GUI = Window()
sys.exit(app.exec_())
run()
I have two toolbars.I am planning to use cursorPositionChanged to do this but still is there a way in PyQt to do this
reproduible code:
https://files.fm/u/h4c2amdx
Instead of using QAction you must use QToolButton and set the checkable property to True:
toolButton.setCheckable(True)
Example:
class Window(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.setWindowTitle('Rich Text Editor')
self.statusBar = QStatusBar(self)
self.textEdit = QtGui.QTextEdit(self)
self.setCentralWidget(self.textEdit)
self.setStatusBar(self.statusBar)
self.home()
def home(self):
toolButton = QToolButton(self)
toolButton.setIcon(QtGui.QIcon('bold-text-option.png'))
toolButton.setCheckable(True)
toolButton.toggled.connect(self.onToggled)
self.formatbar = QToolBar(self)
self.addToolBar(Qt.TopToolBarArea, self.formatbar)
self.formatbar.addWidget(toolButton)
def onToggled(self, checked):
print(checked)
Screenshots:
Plus: To set the value manually and to obtain the status the following instructions are used:
toolButton.setChecked(True) # set State
print(toolButton.isChecked()) # get State
toolButton.toggle() # change state
Actions also have a checable flag and they can act as a toggle switch. Sorry, I don’t know English. So I showed it with code.
# add this code before self.formatbar = QToolBar()
# and create img file blue_bold-text-option.png
self.changeBoldActionTB.setCheckable(True)
icon = QIcon()
icon.addFile('bold-text-option.png', QSize(), QIcon.Normal, QIcon.Off)
icon.addFile('blue_bold-text-option.png', QSize(), QIcon.Normal, QIcon.On)
self.changeBoldActionTB.setIcon(icon)

Python PyQt4: Single child window

I have a simple PyQt4 example.
When run, it displays a QMainWindow with a button.
If you click the button, then a second QMainWindow is created.
If you click it again, you get 2 second windows.
What is an elegant and simple way to prevent more than 1 second window in this example?
import sys
from PyQt4.QtGui import *
class win2(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self,parent)
layout = QVBoxLayout()
label = QLabel(self)
label.setText('This is win2')
layout.addWidget(label)
self.adjustSize()
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
layout = QVBoxLayout()
button1 = QPushButton("win2", self)
layout.addWidget(button1)
button1.clicked.connect(self.showwin2)
def showwin2(self):
w2 = win2(self)
w2.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWin = MainWindow()
mainWin.show()
sys.exit(app.exec_())
Your Function creates a new instance of the class win2 each time the button is pressed. To Supress this behavior only call the show and raise_ functions instead of creating a new instance.
I would create the class as follows, and only use the button to 'show' the window. Tested and works as intended. Also consider using self when assigning your variables so they can be accessed throughout the class instance.
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
layout = QVBoxLayout()
button1 = QPushButton("win2", self)
layout.addWidget(button1)
button1.clicked.connect(self.showwin2)
self.w2 = win2(self)
def showwin2(self):
self.w2.show()
self.w2.raise_()

QPushButton no longer responding inside GroupBox

So was creating a QGroupBox with a bunch of buttons, labels contained. Everything was working fine and now all of a sudden the buttons arent clickable. In fact nothing inside the groupbox is clickable. Any ideas? I've been pulling my hair out trying to see where i went wrong.
Have simplified the code down and tested it. No errors just cant click the button. Im wondering if its a parenting issue?
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class PxJob(QWidget):
def __init__(self, parent, geo, title):
super(PxJob, self).__init__(parent)
frame = QGroupBox(parent)
frame.setGeometry(geo)
frame.setTitle(title)
grid = QGridLayout()
frame.setLayout(grid)
butt = QPushButton('test')
butt.setCheckable(True)
grid.addWidget(butt)
class PxManager(QMainWindow):
def __init__(self, *args):
super(PxManager, self).__init__()
self.initUI()
def initUI(self):
# Main Layout
job = PxJob(self, QRect(10,60,830,120), 'Shot 02')
col = QVBoxLayout()
col.addWidget(job)
window = QWidget()
window.setLayout(col)
self.setCentralWidget(window)
self.setGeometry(300, 300, 850, 200)
self.setWindowTitle('Manager')
self.show()
def main():
app = QApplication(sys.argv)
ruc = PxManager()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
You need to add this line at the end of __init__ in PxJob:
self.setLayout(grid)

PyQt widgets in multiple files

i'd like to learn PyQt by writing a simple game. the first widget would have buttons like "New game", "Quit", etc. i am having trouble understanding how to transition from that menu widget to a new one.
for instance, if i were to click New Game, how do i have a new widget appear that replaces the old one and asks for the user's name? the way i am approaching it now is something like
Form = QtGui.QWidget()
ui = uiMainMenu()
ui.setupUi(Form)
Form.show()
then once newGameButton is pressed it would go to a subroutine...
Form2 = QtGui.QWidget()
ui2 = uiNewGame()
ui2.setupUi(Form2)
Form2.show()
i'm not asking for all the code, just an explanation as to how i should be approaching the problem, because the code above ain't doing squat.
thanks!
if you want to switch between forms then you can use QStackedWidget.
Below you can find a working sample code:
import sys
from functools import partial
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class Form1(QWidget):
showForm2Signal = pyqtSignal()
def __init__(self, parent=None):
super(Form1, self).__init__(parent)
self.newGameButton = QPushButton("New Game", self)
self.quitButton = QPushButton("Quit", self)
layout = QVBoxLayout(self)
layout.addWidget(QLabel("<html>My Game<br>Start Page</html>"))
layout.addWidget(self.newGameButton)
layout.addWidget(self.quitButton)
self.newGameButton.clicked.connect(self.showForm2Signal.emit)
self.quitButton.clicked.connect(qApp.quit)
class Form2(QWidget):
showForm1Signal = pyqtSignal()
def __init__(self, parent=None):
super(Form2, self).__init__(parent)
self.backButton = QPushButton("Back", self)
layout = QVBoxLayout(self)
layout.addWidget(QLabel("New Game Started!"))
layout.addWidget(self.backButton)
self.backButton.clicked.connect(self.showForm1Signal.emit)
class MainWidget(QWidget):
def __init__(self, parent=None):
super(MainWidget, self).__init__(parent)
self.stack = QStackedWidget()
layout = QVBoxLayout(self)
layout.addWidget(self.stack)
self.form1 = Form1(self)
self.form2 = Form2(self)
self.stack.addWidget(self.form1)
self.stack.addWidget(self.form2)
self.form1.showForm2Signal.connect(partial(self.stack.setCurrentWidget,
self.form2))
self.form2.showForm1Signal.connect(partial(self.stack.setCurrentWidget,
self.form1))
self.stack.setCurrentWidget(self.form1)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MainWidget()
w.show()
app.exec_()
sys.exit()
If you only want to ask the name to the user then you can use a QDialog widget.

Categories