PyQt5 - How to dynamically add widgets to window without layout - python

I've been trying to figure this one out, the reason I don't want to use a layout is because the widgets scale with the window when resizing and I want them to stay put, I have made it where I can drag and drop the widgets but with them being in a layout it messes it up, please can someone help me figure this out.
I Want to be able to add lets say a label widget, I want to have it where I can press a button and it will create a new label widget in my window, I have done this part already but I want to be able to add widgets without the layout.

You just have to set another widget that is part of the window (or the window itself) as parent and make it visible with the show method:
import random
import sys
from PyQt5 import QtCore, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
button = QtWidgets.QPushButton("Add", self)
button.clicked.connect(self.handle_clicked)
self.resize(640, 480)
def handle_clicked(self):
pos = QtCore.QPoint(*random.sample(range(400), 2))
label = QtWidgets.QLabel(self)
label.move(pos)
label.setText("{}-{}".format(pos.x(), pos.y()))
label.show()
def main():
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec())
if __name__ == "__main__":
main()

Related

Notification when QDockWidget's tab is clicked?

I need to execute a block of code when the user clicks on the tab of a tabbified QDockWidget. So far I've been doing this via a hack using the "visibilityChanged" event but this is now causing issues (for example, if I have several tabbified dock widgets and I drag one out so that it is floating, the tabbified one underneath will fire its "visibilityChanged" event which I will mistakenly interpret as the user clicking the tab). How can I receive proper notification when a user clicks on a QDockWidgets' tab? I've experimented with the "focusInEvent" of QDockWidget but it doesn't seem to fire when the tab is clicked.
When you use tabifyDockWidget() method QMainWindow creates a QTabBar, this is not directly accessible but using findChild() you can get it, and then use the tabBarClicked signal
from PyQt4 import QtCore, QtGui
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
first_dock = None
for i in range(10):
dock = QtGui.QDockWidget("title {}".format(i), self)
dock.setWidget(QtGui.QTextEdit()) # testing
self.addDockWidget(QtCore.Qt.TopDockWidgetArea, dock)
if first_dock:
self.tabifyDockWidget(first_dock, dock)
else:
first_dock = dock
dock.raise_()
tabbar = self.findChild(QtGui.QTabBar, "")
tabbar.tabBarClicked.connect(self.onTabBarClicked)
def onTabBarClicked(self, index):
tabbar = self.sender()
text = tabbar.tabText(index)
print("index={}, text={}".format(index, text))
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())

Pyside GUI function overwrite issue

I am learning to make GUI's in PySide.
How do I re-size the buttons inside a QHBoxLayout()? I tried button_1.setFixedWidth() and button_1.setFixedHeight() these make the buttons non-scalable. button_1.move() also doesn't work.
Also I have created a function angles() which have Qlabel and QLineEdit, when I run the program, the button function is over-writing the angles function to display only buttons at right corner of the GUI.
And how to resize the length of the QLineEdit and for it to not extend the whole window?
import sys
from PySide.QtGui import *
from PySide.QtCore import *
class MainWindow(QMainWindow):
#GUI Layout
def __init__(self,parent = None):
super(MainWindow, self).__init__(parent)
widget = QWidget()
self.setCentralWidget(widget)
self.setWindowTitle("Example")
self.setGeometry(400, 100, 1500, 800)
self.angles()
self.makebuttons()
def angles(self):
central_widget = QWidget()
self.setCentralWidget(central_widget)
Rotation = QLabel('Rotation:')
Tilt = QLabel('Tilt:')
RoatationEdit = QLineEdit()
TiltEdit = QLineEdit()
grid = QGridLayout()
grid.setSpacing(2)
grid.addWidget(Rotation,1,0)
grid.addWidget(RoatationEdit, 1, 1)
grid.addWidget(Tilt,2,0)
grid.addWidget(TiltEdit, 2, 1)
central_widget.setLayout(grid)
def makebuttons(self):
central_widget = QWidget()
self.setCentralWidget(central_widget)
hbox = QHBoxLayout()
button_1 = QPushButton("Button 1",self)
button_1.move(0,30)
hbox.addStretch(1)
button_2 = QPushButton("Button 2",self)
hbox.addStretch(1)
hbox.addWidget(button_1)
hbox.addWidget(button_2)
vbox = QVBoxLayout()
vbox.addStretch(1)
vbox.addLayout(hbox)
central_widget.setLayout(vbox)
# central_widget.addLayout(vbox)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
If you want to resize use: button_1.setFixedSize({your scale}*button_1.size())
The makebuttons function creates another centralWidget by deleting all of the above, so you will not see what you did with angles.
To change the width of QLineEdit use {your QlineEdit} .setFixedWidth({your width})
I use Qt Designer for all of my Pyside GUI work, even if it's a fairly trivial program. It's much more than just a drag-and-drop WYSISYG tool. For things like push buttons in your example, you would be presented with a list of configurable properties including sizing parameters of the button as well as the ability to configure the layout.
So, my solution is to create your GUI in QT Designer then modify the layout there before using the pyside-uic tool to convert the code to python. Then just import the resulting python module into your code. From there you can still re-configure whatever you want later in your code if, for example, you need to change the appearance of your GUI during the course of your program.

Button not displayed in the right place

I am using PyQt to create a desktop application. I am trying to create a button using hbox and vbox, but it doesn't display unless I give the specific command:
button1 = QtGui.QPushButton("Exit", self)
But, by doing this, the vbox and hbox functionality doesn't seem to function.
I need the button to be on the bottom-right corner of the window, which stays there even after window-resize.
With this code, it is positioned on the top-left corner.
from PyQt4 import QtGui, QtCore
import sys
class Trial(QtGui.QMainWindow):
def __init__(self):
super(Trial,self).__init__()
self.createUI()
def createUI(self):
button1 = QtGui.QPushButton("Exit",self)
button1.clicked.connect(self.close)
hbox = QtGui.QHBoxLayout()
hbox.addStretch(1) #stretches it to the right end of the page
hbox.addWidget(button1)
vbox = QtGui.QVBoxLayout()
vbox.addStretch(1) #stretches it to the bottom end of the page
vbox.addLayout(hbox)
self.setLayout(vbox)
button1.resize(button1.sizeHint())
self.setGeometry(300,200,750,450)
self.setWindowTitle('Testing')
self.show()
def main():
app= QtGui.QApplication(sys.argv)
w=Trial()
sys.exit(app.exec_())
if __name__=='__main__':
main()
If I use button1.move(420, 400), it moves the button to the position I want, but it doesn't stay there when I re-size the application window.
The example code doesn't work because you are trying to set a layout on the main window, which already has a layout.
Instead, you need to add a central widget, and then set the layout on that:
def createUI(self):
self.setCentralWidget(QtGui.QWidget(self))
...
vbox.addLayout(hbox)
self.centralWidget().setLayout(vbox)
self.setGeometry(300,200,750,450)
...

PyQt4 menu acction to add new tab to QTabWidget

I'm working on a small application for work w/ python and PyQt4 for the GUI. What I'm trying to accomplish is having a tabbed GUI where when a user clicks on a menu item, the action taken adds a tab to the QTabWidget. I'm currently having trouble getting an action to do such a thing. I've tried creating the GUI by hand and with QT designer, but I cant figure out how, if at all possible, to get an action to add a tab to the QTabWidget. This is my python code:
import sys
from PyQt4 import QtGui, uic
class TestGUI(QtGui.QMainWindow):
def __init__(self):
super(TestGUI, self).__init__()
uic.loadUi('TEST.ui', self)
self.show()
self.actionAdd_Tab.triggered.connect(addTab)
def addTab():
print 'This works'
#Add new tab to GUI
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = TestGUI()
sys.exit(app.exec_())
Pressing the menu item prints 'This works' to the console, so I know that its calling the addTab() function, but how do I get it to add a Tab?
Let me know if you would like to see the .ui file if it will help
The handler for your action needs to create a tab label, and also a widget for the contents of the tab, so that they can be added to the tabwidget.
As a start, try something like this:
import sys
from PyQt4 import QtGui, uic
class TestGUI(QtGui.QMainWindow):
def __init__(self):
super(TestGUI, self).__init__()
uic.loadUi('TEST.ui', self)
self.actionAdd_Tab.triggered.connect(self.handleAddTab)
def handleAddTab(self):
contents = QtGui.QWidget(self.tabWidget)
layout = QtGui.QVBoxLayout(contents)
# add other widgets to the contents layout here
# i.e. layout.addWidget(widget), etc
self.tabWidget.addTab(contents, 'Tab One')
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = TestGUI()
window.show()
sys.exit(app.exec_())
QTabWidget's addTab() method, coincidentally named the same, adds a tab.

Hover issue in PyQt

I want to do hover. I saw an example and then write a script which will be use as I made program. I am facing one problem that hover only occur if you put mouse on the left corner of button. I want that it will happen for all the button that if i move cursor on button then it should change.
Here is my code:
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import pyqtSignal
import os,sys
class HoverButton(QtGui.QToolButton):
def enterEvent(self,event):
print("Enter")
button.setStyleSheet("background-color:#45b545;")
def leaveEvent(self,event):
button.setStyleSheet("background-color:yellow;")
print("Leave")
app = QtGui.QApplication(sys.argv)
widget = QtGui.QWidget()
button = QtGui.QToolButton(widget)
button.setMouseTracking(True)
buttonss = HoverButton(button)
button.setIconSize(QtCore.QSize(200,200))
widget.show()
sys.exit(app.exec_())
Is this what you're looking for
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import pyqtSignal
import os,sys
class Main(QtGui.QWidget):
def __init__(self, parent=None):
super(Main, self).__init__(parent)
layout = QtGui.QVBoxLayout(self) # layout of main widget
button = HoverButton(self)
button.setIconSize(QtCore.QSize(200,200))
layout.addWidget(button) # set your button to the widgets layout
# this will size the button nicely
class HoverButton(QtGui.QToolButton):
def __init__(self, parent=None):
super(HoverButton, self).__init__(parent)
self.setMouseTracking(True)
def enterEvent(self,event):
print("Enter")
self.setStyleSheet("background-color:#45b545;")
def leaveEvent(self,event):
self.setStyleSheet("background-color:yellow;")
print("Leave")
app = QtGui.QApplication(sys.argv)
main = Main()
main.show()
sys.exit(app.exec_())
In your code you had a button in a button and the nested button wasn't assigned to a QLayout widget. Although, I'm not sure why you're adding a button inside of a button. One thing that I've learned from working with GUI's is that it's so much easier if you modularize your code. Now you can take this custom button and apply it somewhere else.
You should use the stylesheet as
QToolButton:hover
{
background-color: rgb(175,175,175);
}
You probably want focus and blur, rather than enter and leave will only fire when the mouse actually enters or leaves the boundary of the button and will probably just be short duration impulses rather than toggles. focus and blur will toggle with the hover.

Categories