I have two radioButtons in the form made using qt designer, i am now programming in pyqt. i wish to change the text of lineEdit to "radio 1" when radioButton 1 is selected and "radio 2" when the radioButton 2 is selected. how can I achieve this?
Here's a simple example. Each QRadioButton is connected to it's own function. You could connect them both to the same function and manage what happens through that, but I thought best to demonstrate how the signals and slots work.
For more info, take a look at the PyQt4 documentation for new style signals and slots. If connecting multiple signals to the same slot it's sometimes useful to use the .sender() method of a QObject, although in the case of QRadioButton it's probably easier to just check the .isChecked() method of your desired buttons.
import sys
from PyQt4.QtGui import QApplication, QWidget, QVBoxLayout, \
QLineEdit, QRadioButton
class Widget(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.widget_layout = QVBoxLayout()
self.radio1 = QRadioButton('Radio 1')
self.radio2 = QRadioButton('Radio 2')
self.line_edit = QLineEdit()
self.radio1.toggled.connect(self.radio1_clicked)
self.radio2.toggled.connect(self.radio2_clicked)
self.widget_layout.addWidget(self.radio1)
self.widget_layout.addWidget(self.radio2)
self.widget_layout.addWidget(self.line_edit)
self.setLayout(self.widget_layout)
def radio1_clicked(self, enabled):
if enabled:
self.line_edit.setText('Radio 1')
def radio2_clicked(self, enabled):
if enabled:
self.line_edit.setText('Radio 2')
if __name__ == '__main__':
app = QApplication(sys.argv)
widget = Widget()
widget.show()
sys.exit(app.exec_())
Related
I've created a QMenu in a widget outside of my main window, but when I try to show it on my Application it simply doesn't appear.
If I create the exact same QMenu in my main window class it appears without any issue.
from PyQt5.QtWidgets import (
QApplication,
QHBoxLayout,
QWidget,
QPushButton,
QMenu,
QAction
)
from PyQt5 import QtCore
class testWidget(QWidget):
def __init__(self):
menu = QMenu()
action = QAction("Test", checkable = True)
menu.addAction(action)
menu.addSeparator()
self.menu = menu
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Test pricer")
self.mainLayout = QHBoxLayout()
self.setLayout(self.mainLayout)
self.resize(900, 600)
self.button = QPushButton("Show menu")
self.button.clicked.connect(self.showMenu)
self.mainLayout.addWidget(self.button)
self.testWidget = testWidget()
def showMenu(self):
print(self.testWidget.menu.actions())
#self.testWidget.menu.setParent(self)
self.testWidget.menu.exec_(QtCore.QPoint(200, 200))
if __name__ == "__main__":
app = 0
app = QApplication([])
window = Window()
window.show()
app.exec_()
I tried changing the parent of the menu to the main window but that doesn't solve the problem either.
Would anyone know a way to show the menu while still creating it in another widget?
The QMenu is shown but not the item "Test" so the window is very small. "Test" is not displayed because QAction is removed since it is a local variable and no other variable takes ownership. There are 2 solutions:
Pass a parent to QAction: action = QAction("Test", checkable = True, parent=menu)
Make the QAction an attribute of the class by changing action to self.action.
I am trying to create a GUI for my python program. One of the tools that I need is a text input box.
Now, I want a text label for this box saying "Please insert texts." Is there a function to add a label that shows inside the input textbox as default and disappear when user click the box to type?
I don't mind to use qt designer or pyqt5 coding.
Thank you guys.
placeholderText : QString
This property holds the line edit's placeholder text
import sys
from PyQt5.QtWidgets import QLineEdit, QVBoxLayout, QApplication, QWidget
class Test(QWidget):
def __init__(self):
super().__init__()
self.lineEdit = QLineEdit(placeholderText="Please insert texts.") # <---
vbox = QVBoxLayout(self)
vbox.addWidget(self.lineEdit)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = Test()
w.show()
sys.exit(app.exec_())
I am begginer like you and my English is not so good. But I recommend you use Qt Designer. It's easier, fastter for you draw your app. I am using pyside2 project and recommend you read docummentatio each widgets you wanna use in PySide2 project and Qt Project. Try code below
enter image description here
import sys
from PySide2.QtWidgets import QApplication
from PySide2.QtWidgets import QDialog
from PySide2.QtWidgets import QTextEdit
from PySide2.QtWidgets import QVBoxLayout
from PySide2.QtCore import Qt
class MainDialog(QDialog):
def __init__(self, parent=None):
super(MainDialog, self).__init__(parent)
# Create Widget TextEdit
self.text = QTextEdit()
# I think that you wanna this function in your program
# https://doc.qt.io/qtforpython/PySide2/QtWidgets/QLineEdit.html?highlight=qlineedit#PySide2.QtWidgets.PySide2.QtWidgets.QLineEdit.setPlaceholderText
# http://doc.qt.io/qt-5/qlineedit.html#placeholderText-prop
self.text.setPlaceholderText('''Yes! this is exactly what I want!
Thank you, what if you have a big text box (more than 10 lines) and
you want to scale up the place holder and align it in center?? ''')
# https://doc.qt.io/qtforpython/PySide2/QtWidgets/QLineEdit.html?highlight=qlineedit#PySide2.QtWidgets.PySide2.QtWidgets.QLineEdit.setAlignment
# http://doc.qt.io/qt-5/qlineedit.html#alignment-prop
self.text.setAlignment(Qt.AlignCenter)
# Layout
layout = QVBoxLayout()
layout.addWidget(self.text)
self.setLayout(layout)
def main():
app = QApplication()
mainDialog = MainDialog()
mainDialog.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
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.
In this sample of code:
from PyQt4.QtGui import QDialog, QPushButton, QRadioButton, QHBoxLayout, QApplication, QButtonGroup
import sys
class Form(QDialog):
def __init__(self, parent=None):
super(Form, self).__init__(parent=None)
button = QPushButton('Button')
self.radiobutton1 = QRadioButton('1')
self.radiobutton2 = QRadioButton('2')
#self.group = QButtonGroup()
#self.group.addButton(self.radiobutton1)
#self.group.addButton(self.radiobutton2)
#self.group.setExclusive(False)
layout = QHBoxLayout()
layout.addWidget(button)
layout.addWidget(self.radiobutton1)
layout.addWidget(self.radiobutton2)
self.setLayout(layout)
button.clicked.connect(self.my_method)
def my_method(self):
self.radiobutton1.setChecked(False)
self.radiobutton2.setChecked(False)
app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()
When the button clicked I expect the selected radioButton to be unchecked, but that never happens. If I uncomment the comment lines and run the code, then I can uncheck radioButtons. But another problem occurs. Because the group is not exclusive, I can set both radioButtons checked something that must not happens.
What should I do to be able to unckeck the buttons while only one button at a time can be selected?
This feels like cheating, but it works:
import sys
import PyQt4.QtGui as QtGui
class Form(QtGui.QDialog):
def __init__(self, parent=None):
super(Form, self).__init__(parent)
button = QtGui.QPushButton('Button')
button.clicked.connect(self.my_method)
self.radiobutton1 = QtGui.QRadioButton('1')
self.radiobutton2 = QtGui.QRadioButton('2')
layout = QtGui.QHBoxLayout()
layout.addWidget(button)
layout.addWidget(self.radiobutton1)
layout.addWidget(self.radiobutton2)
self.setLayout(layout)
self.group = QtGui.QButtonGroup()
self.group.addButton(self.radiobutton1)
self.group.addButton(self.radiobutton2)
def my_method(self):
self.group.setExclusive(False)
self.radiobutton1.setChecked(False)
self.radiobutton2.setChecked(False)
self.group.setExclusive(True)
app = QtGui.QApplication(sys.argv)
form = Form()
form.show()
app.exec_()
As you've pointed out, when self.group.setExclusive(False) is set, you can untoggle both radio buttons.
And when self.group.setExclusive(True), only one radio button can be set.
So my_method simply calls self.group.setExclusive(False) so it can unset both radio buttons, then resets self.group.setExclusive(True).
PS. I think parent should not be set to None on this line:
super(Form, self).__init__(parent = None)
since if a non-trivial parent is sent to Form, you would probably want to pass that parent on to QDialog.__init__.
To anyone looking for a simple fix to this very annoying problem, connect each button to a slot that controls the CheckState of the other buttons.
Simply add the list of buttons you want to a QButtonGroup, get the list of buttons, check that the sender is not the same button, and uncheck others.
Assuming that you instantiate your buttons in a loop, you can easily implement this:
self.bg = QButtonGroup()
self.bg.setExclusive(False)
for button in list_of_buttons:
self.bg.addButton(button)
button.clicked.connect(self.uncheck_other_buttons)
def uncheck_other_btns(self):
for button in self.bg.buttons(): # returns the list of all added buttons
if self.sender() != button: # in PyQt5, button.objectName() fails if name isn't set,
# instead, simply check that the signal sender() object
# is not the same object as the clicked button
button.setChecked(False) # then set all other buttons to be unchecked
I'm having a problem with QComboBox not allowing me to change the edit
text to anything existing item of differing case.
Example code is below. What I'd like to do is enter 'one' into a combo
box already containing the item 'One' without the side effect of the
text being changed to 'One'. Currently it's changed back to 'One' as
soon as the combo box loses focus.
Disabling AutoCompletionCaseSensitivity works, but it has the side
effect of not being useful (Doesn't eg. show completions for 'one').
I've also tried overriding the focusOutEvent of QComboBox and
restoring the correct text, but then things like copy-paste don't
work. Changing the completer hasn't helped any either.
The fact combo boxes behave this way is detrimental to my app. If
anyone has any ideas (or I missed something obvious), please let me
know.
I'm using Qt 4.6.2 and PyQt 4.7.2 on Ubuntu 10.04, but have
experienced this on other distros/Qt versions above 4.5.
Thanks and Regards
Example Code:
from PyQt4.QtGui import *
from PyQt4.QtCore import SIGNAL, Qt
class Widget(QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
combo = QComboBox()
combo.setEditable(True)
combo.addItems(['One', 'Two', 'Three'])
lineedit = QLineEdit()
layout = QVBoxLayout()
layout.addWidget(combo)
layout.addWidget(lineedit)
self.setLayout(layout)
app = QApplication([])
widget = Widget()
widget.show()
app.exec_()
from PyQt4.QtGui import *
from PyQt4.QtCore import SIGNAL, Qt, QEvent
class MyComboBox(QComboBox):
def __init__(self):
QComboBox.__init__(self)
def event(self, event):
if event.type() == QEvent.KeyPress and event.key() == Qt.Key_Return:
self.addItem(self.currentText())
return QComboBox.event(self, event)
class Widget(QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
combo = MyComboBox()
combo.setEditable(True)
combo.addItems(['One', 'Two', 'Three'])
lineedit = QLineEdit()
layout = QVBoxLayout()
layout.addWidget(combo)
layout.addWidget(lineedit)
self.setLayout(layout)
app = QApplication([])
widget = Widget()
widget.show()
app.exec_()
The only issue with this is that it will allow adding duplicates to your combobox.
I tried adding a self.findText(...) to the if statement but even Qt.MatchExactly | Qt.MatchCaseSensitive
would match "bla", "bLa" and "BLA".
I guess you'll find out.