I have a QVBoxLayout where I put some buttons. I wrote a function to remove a button, but when I do it, the box doesn't adapt its size to the content.
Here is a piece of the removal function:
for each_difference in differences_remove:
old_index = self.all_tags.index(each_difference)
print("old" + str(old_index))
self.vbox_all_tags.removeWidget(self.liste_pressoirs[old_index])
del self.liste_pressoirs[old_index]
I would like self.vbox_all_tags to adapt its size to the new content after I remove a button. How would you do that ?
Kindly.
Just call adjustSize on your widget after removing the button, here is a demonstration:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from PyQt4 import QtCore, QtGui
class MyWindow(QtGui.QWidget):
_buttons = []
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
self.pushButtonRemove = QtGui.QPushButton(self)
self.pushButtonRemove.setText("Remove A Button!")
self.pushButtonRemove.clicked.connect(self.on_pushButtonRemove_clicked)
self.widgetButtons = QtGui.QWidget(self)
self.layoutButtons = QtGui.QHBoxLayout(self.widgetButtons)
self.layout = QtGui.QVBoxLayout(self)
self.layout.addWidget(self.pushButtonRemove)
self.layout.addWidget(self.widgetButtons)
for buttonNumber in range(3):
pushButton = QtGui.QPushButton()
pushButton.setText("Button {0}".format(buttonNumber))
self._buttons.append(pushButton)
self.layoutButtons.addWidget(pushButton)
#QtCore.pyqtSlot()
def on_pushButtonRemove_clicked(self):
if self._buttons:
pushButton = self._buttons[-1]
self._buttons.pop()
self.layoutButtons.removeWidget(pushButton)
pushButton.deleteLater()
self.widgetButtons.adjustSize()
self.adjustSize()
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
app.setApplicationName('MyWindow')
main = MyWindow()
main.show()
sys.exit(app.exec_())
Related
I'm using the QPushButton to load the UI. First -> Jumin -> Department -> next -> next I want to create the UI in order. The problem is that I can not load the third Department into the QMainwindow window. I do not know why
When you create a widget in QVBoxLayout, it changes the size of the widget according to the wallpaper like wxpython layout (wx.all). Can not change the position (move) and size (resize) by automatic centering?
import sys
from PyQt5.QtWidgets import *
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.center_widget = QWidget()
self.setCentralWidget(self.center_widget)
self.FirstUI()
def FirstUI(self):
self.btn1 = QPushButton('test1', self)
self.btn1.move(50, 50)
self.btn1.clicked.connect(self.btn1_click)
def JuminUI(self):
self.ju1 = QLineEdit('13')
self.btn2 = QPushButton('^^^^^^^^^^')
self.ju_text = QLabel('asd')
self.jumim_layout = QVBoxLayout()
self.jumim_layout.addWidget(self.ju_text)
self.jumim_layout.addWidget(self.ju1)
self.jumim_layout.addWidget(self.btn2)
self.centralWidget().setLayout(self.jumim_layout)
self.btn2.clicked.connect(self.btn2_click)
def DepartmentUI(self):
self.depart_layout = QVBoxLayout()
self.depart_layout.addWidget(QPushButton('sdfsdf'))
self.centralWidget().setLayout(self.depart_layout)
def btn1_click(self):
self.btn1.deleteLater()
self.JuminUI()
def btn2_click(self):
self.ju1.deleteLater()
self.btn2.deleteLater()
self.ju_text.deleteLater()
self.DepartmentUI()
if __name__ == "__main__":
app = QApplication(sys.argv)
fream = MainWindow()
fream.show()
app.exec_()
creating and removing widgets is almost always a bad idea, and your code falls into those bad ideas, it's always best to hide the widgets and for that you should use the QStackedWidget, what QStackedWidget does is just make a widget visible on all widgets that you have been assigned by changing the currentIndex.
import sys
from functools import partial
from PyQt5 import QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.center_widget = QtWidgets.QStackedWidget()
self.setCentralWidget(self.center_widget)
self.FirstUI()
self.JuminUI()
self.DepartmentUI()
def FirstUI(self):
widget = QtWidgets.QWidget()
self.btn1 = QtWidgets.QPushButton('test1', widget)
self.btn1.move(50, 50)
self.center_widget.addWidget(widget)
self.btn1.clicked.connect(partial(self.center_widget.setCurrentIndex, 1))
def JuminUI(self):
widget = QtWidgets.QWidget()
lay = QtWidgets.QVBoxLayout(widget)
self.ju1 = QtWidgets.QLineEdit('13')
self.btn2 = QtWidgets.QPushButton('^^^^^^^^^^')
self.ju_text = QtWidgets.QLabel('asd')
lay.addWidget(self.ju_text)
lay.addWidget(self.ju1)
lay.addWidget(self.btn2)
self.center_widget.addWidget(widget)
self.btn2.clicked.connect(partial(self.center_widget.setCurrentIndex, 2))
def DepartmentUI(self):
widget = QtWidgets.QWidget()
lay = QtWidgets.QVBoxLayout(widget)
lay.addWidget(QtWidgets.QPushButton('sdfsdf'))
self.center_widget.addWidget(widget)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
fream = MainWindow()
fream.show()
sys.exit(app.exec_())
I have the following window with frames.
I want frame to be highlighted (in my case change its shape) when mouse is in its area.
from PyQt4 import QtGui, QtCore
import sys
app = QtGui.QApplication(sys.argv)
window = QtGui.QWidget()
window_layout = QtGui.QVBoxLayout()
window.setLayout(window_layout)
#fill content
for i in range(10):
label = QtGui.QLabel(str(i))
frame = QtGui.QFrame()
frame_layout = QtGui.QVBoxLayout()
frame.setLayout(frame_layout)
frame_layout.addWidget(label)
window_layout.addWidget(frame)
def layout_widgets(layout):
return (layout.itemAt(i) for i in range(layout.count()))
def mouse_enter(event):
print 'frame enter'
w.widget().setFrameShape(3)
def mouse_leave(event):
print 'frame leave'
w.widget().setFrameShape(0)
for w in layout_widgets(window_layout):
print w.widget()
w.widget().enterEvent = mouse_enter
w.widget().leaveEvent = mouse_leave
window.show()
sys.exit(app.exec_())
It works but only the last frame in layout highlights.
How to make only that frame change its shape where the mouse is?
I've tried the following:
def mouse_enter(event, frame):
print 'frame enter'
frame.setFrameShape(3)
w.widget().enterEvent = functools.partial(mouse_enter, w.widget())
but it gives an error. I have found one more way to do that - signal mapper
but I have no idea how to use it.
The problem in your code the variable w when executing the for is left with the last element, so it will only be executed in the latter. To solve this I have implemented a Frame class that inherits from QFrame where I overwrite the enterEvent and leaveEvent functions.
from PyQt4 import QtGui, QtCore
import sys
class Frame(QtGui.QFrame):
def __init__(self, text, parent=None):
super(Frame, self).__init__(parent=parent)
label = QtGui.QLabel(text)
frame_layout = QtGui.QVBoxLayout()
frame_layout.addWidget(label)
self.setLayout(frame_layout)
def enterEvent(self, event):
self.setFrameShape(3)
def leaveEvent(self, event):
self.setFrameShape(0)
app = QtGui.QApplication(sys.argv)
window = QtGui.QWidget()
window_layout = QtGui.QVBoxLayout()
window.setLayout(window_layout)
for i in range(10):
frame = Frame(str(i))
window_layout.addWidget(frame)
window.show()
sys.exit(app.exec_())
I want to find QLabel with specific text and focus view on it. Finding widget with desired text is easy, but I couldn't figure out how to focus view on it.
The code so far looks like this:
import sys
from PySide import QtCore, QtGui
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super().__init__()
widget = QtGui.QWidget()
self.layout = QtGui.QGridLayout()
for i in range(10):
label = QtGui.QLabel("aaaa" + str(i))
self.layout.addWidget(label, i, 0)
widget.setLayout(self.layout)
self.toolbar = self.addToolBar("aa")
findAction = QtGui.QAction('Find', self)
findAction.triggered.connect(self.find)
self.toolbar.addAction(findAction)
self.scroll = QtGui.QScrollArea()
self.scroll.setWidget(widget)
self.scroll.setWidgetResizable(True)
self.setMaximumSize(200, 200)
self.setCentralWidget(self.scroll)
def find(self):
widgets = (self.layout.itemAt(i).widget() for i in range(self.layout.count()))
for w in widgets:
if isinstance(w, QtGui.QLabel):
if w.text() == "aaaa9":
w.setFocus()
def main():
app = QtGui.QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
app.exec_()
if __name__ == "__main__":
main()
Any ideas how to get focus working?
You can use ensureWidgetVisible()
self.scroll.ensureWidgetVisible(w)
I have a button and a text label. Each time the button is pressed, i would like text placed from a line edit to be placed onto the window. So far I can only get one text to draw onto the window, even if I create another textlabel. Ive tried seeting a click count determining how many times a user has clicked a button but this doesnt work either. Heres what I have so far, any suggestions?
import sys
import os
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtGui import QApplication
class Window(QMainWindow):
def __init__(self, *args):
QMainWindow.__init__(self, *args)
self.centralWidget = QWidget(self)
self.setCentralWidget(self.centralWidget)
self.setGeometry(450,100,350,680)
self.btn1 = QPushButton("Enter", self.centralWidget)
self.btn1.setGeometry(10,50,150, 20)
self.btn1.clicked.connect(self.enter)
self.edit = QtGui.QLineEdit(self)
self.edit.setGeometry(10, 10, 150, 20)
self.label = QtGui.QLabel(self)
self.label.setGeometry(240, 170,150, 20)
def enter(self):
self.label.setText(self.edit.text())
def main(args):
global app
app = App(args)
app.exec_()
class App(QApplication):
def __init__(self, *args):
QApplication.__init__(self, *args)
self.main = Window()
self.connect(self, SIGNAL("lastWindowClosed()"), self.byebye )
self.main.show()
def byebye( self ):
self.exit(0)
if __name__ == "__main__":
main(sys.argv)
There are a few problems with your example code, the main one being that you are trying to manually arrange the widgets, rather than using a layout.
It's hard to tell from your question exactly what you expect the output to be, so I've assumed you want the text from line-edit to be appended to the label, so that you end up with a series of lines.
Here's a simplified version of your example that hopefully does what you want:
from PyQt4 import QtCore, QtGui
class Window(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.btn1 = QtGui.QPushButton("Enter", self)
self.btn1.clicked.connect(self.enter)
self.edit = QtGui.QLineEdit(self)
self.label = QtGui.QLabel(self)
self.label.setAlignment(
QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft)
widget = QtGui.QWidget(self)
layout = QtGui.QVBoxLayout(widget)
layout.addWidget(self.edit)
layout.addWidget(self.btn1)
layout.addWidget(self.label)
self.setCentralWidget(widget)
def enter(self):
text = self.edit.text()
if text:
self.label.setText('%s\n%s' % (self.label.text(), text))
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(450, 100, 350, 680)
window.show()
sys.exit(app.exec_())
Let's say I created two QObject in my interface (ui). I would like to connect these two widgets and let them controling each other depending on their visual status. If one is hidden, the other one must be visible. And vice versa.
Can you help me ? :)
Thanks !
Nico
Possible solution: Sublclass widgets and override hideEvent and showEvent:
#!/usr/bin/env python
import sys
from PyQt4 import QtCore, QtGui
class CustomWidget(QtGui.QLabel):
signal_hided = QtCore.pyqtSignal()
signal_shown = QtCore.pyqtSignal()
def hideEvent(self, event):
print 'hideEvent'
super(CustomWidget, self).hideEvent(event)
self.signal_hided.emit()
def showEvent(self, event):
print 'showEvent'
super(CustomWidget, self).showEvent(event)
self.signal_shown.emit()
class MainWidget(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.widget1 = CustomWidget('Widget1')
self.widget2 = CustomWidget('Widget2')
# connect signals, so if one widget is hidden then other is shown
self.widget1.signal_hided.connect(self.widget2.show)
self.widget2.signal_hided.connect(self.widget1.show)
self.widget2.signal_shown.connect(self.widget1.hide)
self.widget1.signal_shown.connect(self.widget2.hide)
# some test code
self.button = QtGui.QPushButton('test')
layout = QtGui.QVBoxLayout()
layout.addWidget(self.button)
layout.addWidget(self.widget1)
layout.addWidget(self.widget2)
self.setLayout(layout)
self.button.clicked.connect(self.do_test)
def do_test(self):
if self.widget1.isHidden():
self.widget1.show()
else:
self.widget2.show()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
widget = MainWidget()
widget.resize(640, 480)
widget.show()
sys.exit(app.exec_())