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)
Related
I have a QGroupBox with a title '123'. Inside the QGroupBox, there should be a QScrollArea. That means that the title '123' of QGrouBox should be outside of the QScrollArea.
My sample codes are as below.
import sys
import PyQt4
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class Example(QWidget):
def __init__(self, parent = None):
super().__init__()
btn = QPushButton('button')
scroll = QScrollArea()
scroll.setWidgetResizable(True)
scroll.setWidget(btn)
groupbox = QGroupBox('123')
groupbox.setLayout(scroll)
self.show()
def main():
app = QApplication(sys.argv)
main = Example()
main.show()
sys.exit(app.exec_())
As you can see above, now it returns TypeError: setLayout(self, QLayout): argument 1 has unexpected type 'QScrollArea'.
I'm just wondering if this is achievable? Thanks!!
When you want to add the content to a QGroupBox you must do through a layout that contains the necessary widgets, in this case as it is only a widget we can use any layout, and in this layout we add the widget that this case is the QScrollArea as sample then:
class Example(QWidget):
def __init__(self, parent = None):
super().__init__()
self.setLayout(QVBoxLayout())
btn = QPushButton('button')
scroll = QScrollArea()
scroll.setWidgetResizable(True)
scroll.setWidget(btn)
groupbox = QGroupBox('123', self)
groupbox.setLayout(QVBoxLayout())
groupbox.layout().addWidget(scroll)
self.layout().addWidget(groupbox)
Screenshot:
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_()
Look at the code
import sys
from PySide import QtCore, QtGui
class MyWidget(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.quit = QtGui.QPushButton("Quit", self)
self.setGeometry(300, 300, 250, 150)
self.statusBar().showMessage('Ready')
app = QtGui.QApplication(sys.argv)
widget = MyWidget()
widget.show()
sys.exit(app.exec_())
Now all I want to do , is add a Status. Now status is available in QtGui.QMainWindow
How can i use this fact to add it in the above program? In pyside coding , seems like for every component , we need to make a class and some connect to the main class..whata s the theory here?
I tried myself like this , but it did not work.
import sys
from PySide import QtCore, QtGui
class MyWidget(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.quit = QtGui.QPushButton("Quit", self)
self.setGeometry(300, 300, 250, 150)
self.statusBar().showMessage('Ready')
self.s = MyStatus()
class MyStatus(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.statusBar().showMessage('Ready')
app = QtGui.QApplication(sys.argv)
widget = MyWidget()
widget.show()
sys.exit(app.exec_())
You do not need to make a class for every component, but if you want to modify/override each component's built-in function you need to make a class for it.
To add something to your main window, you simply have to create an object and add it to the layout. As follow:
import sys
from PySide import QtGui , QtCore
class MyStatusBar(QtGui.QStatusBar):
def __init__(self, parent=None):
super(MyStatusBar, self).__init__(parent)
#Override any functions, or define new function for our status bar here
class MyMainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
#Set the size of the window
self.setMinimumSize(300,300)
#Create a status bar, from our OWN class
self.status_bar = MyStatusBar(self)
self.status_bar.setGeometry(QtCore.QRect(0, 0, 50, 50))
self.status_bar.showMessage('Ready')
#Add a simple quit button, from the DEFAULT class
self.quit_button = QtGui.QPushButton(self)
self.quit_button.clicked.connect(self.close)
self.quit_button.setGeometry(QtCore.QRect(100, 100, 100, 35))
self.quit_button.setText("Close")
#Start the application
app = QtGui.QApplication(sys.argv)
top = MyMainWindow()
top.show()
app.exec_()
If you want a window with a status-bar, use QMainWindow: it has one built-in (and also a menu-bar, tool-bars, dock-widgets, etc). Other widgets don't have these built-in features, and so, quite naturally, they don't have things like a statusBar method. If you insist on doing things the hard way by not using QMainWindow, you will have to add all these features yourself.
Although I wouldn't recommend doing things this way, here is a simple demo that adds a status-bar to a QWidget:
import sys
from PySide import QtCore, QtGui
class MyWidget(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.central_widget = QtGui.QWidget(self)
self.quit = QtGui.QPushButton("Quit", self)
self.setGeometry(300, 300, 250, 150)
layout = QtGui.QVBoxLayout(self.central_widget)
layout.addWidget(self.quit)
self.status = QtGui.QStatusBar(self)
layout = QtGui.QVBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.addWidget(self.widget)
layout.addStretch()
layout.addWidget(self.status)
self.status.showMessage('Ready')
app = QtGui.QApplication(sys.argv)
widget = MyWidget()
widget.show()
sys.exit(app.exec_())
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).
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.