How To connect QComboBox with QlineEdit in PyQt5
I’m developing a PyQt5 desktop GUI app, but am try to connect my comboBox such that, changing the variable in the combobox changes the values in the QlineEdit, please any help will be appreciated. Thanks I have tried several codes but it seems their syntax was not corresponding. below is my code.
from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def event(self): # get value of the selected combobox data V = float(self.input1.text()) U = float(self.input2.text()) t = float(self.input3.text()) a = float(self.input4.text()) #conditions #if u,t,a are given, use this formulars V = U + a*t S = U*t + (a*t**2)/2 t = (V - U)/a #if u,a,s are given, V =(U**2 + 2*a*S)**0.5 S = (V**2 - U**2)/2*a #set the selected combobox result self.lineEdit_result.setText def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(347, 219) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.comboBox = QtWidgets.QComboBox(self.centralwidget) self.comboBox.setGeometry(QtCore.QRect(20, 40, 31, 22)) self.comboBox.setObjectName("comboBox") self.comboBox.addItem("") self.comboBox.addItem("") self.comboBox.addItem("") self.comboBox.addItem("") self.comboBox.addItem("") self.input1 = QtWidgets.QLineEdit(self.centralwidget) self.input1.setGeometry(QtCore.QRect(60, 40, 113, 20)) self.input1.setObjectName("input1") self.comboBox_1 = QtWidgets.QComboBox(self.centralwidget) self.comboBox_1.setGeometry(QtCore.QRect(20, 70, 31, 22)) self.comboBox_1.setObjectName("comboBox_1") self.comboBox_1.addItem("") self.comboBox_1.addItem("") self.comboBox_1.addItem("") self.comboBox_1.addItem("") self.comboBox_1.addItem("") self.input2 = QtWidgets.QLineEdit(self.centralwidget) self.input2.setGeometry(QtCore.QRect(60, 70, 113, 20)) self.input2.setObjectName("input2") self.comboBox_2 = QtWidgets.QComboBox(self.centralwidget) self.comboBox_2.setGeometry(QtCore.QRect(20, 100, 31, 22)) self.comboBox_2.setObjectName("comboBox_2") self.comboBox_2.addItem("") self.comboBox_2.addItem("") self.comboBox_2.addItem("") self.comboBox_2.addItem("") self.comboBox_2.addItem("") self.input3 = QtWidgets.QLineEdit(self.centralwidget) self.input3.setGeometry(QtCore.QRect(60, 100, 113, 20)) self.input3.setObjectName("input3") self.comboBox_3 = QtWidgets.QComboBox(self.centralwidget) self.comboBox_3.setGeometry(QtCore.QRect(20, 130, 31, 22)) self.comboBox_3.setObjectName("comboBox_3") self.comboBox_3.addItem("") self.comboBox_3.addItem("") self.comboBox_3.addItem("") self.comboBox_3.addItem("") self.comboBox_3.addItem("") self.input4 = QtWidgets.QLineEdit(self.centralwidget) self.input4.setGeometry(QtCore.QRect(60, 130, 113, 20)) self.input4.setObjectName("input4") self.comboBox_ANS = QtWidgets.QComboBox(self.centralwidget) self.comboBox_ANS.setGeometry(QtCore.QRect(20, 190, 31, 22)) self.comboBox_ANS.setObjectName("comboBox_ANS") self.comboBox_ANS.addItem("") self.comboBox_ANS.addItem("") self.comboBox_ANS.addItem("") self.comboBox_ANS.addItem("") self.comboBox_ANS.addItem("") self.lineEdit_result = QtWidgets.QLineEdit(self.centralwidget) self.lineEdit_result.setGeometry(QtCore.QRect(60, 190, 113, 20)) self.lineEdit_result.setObjectName("lineEdit_result") self.calcbtn = QtWidgets.QPushButton(self.centralwidget) self.calcbtn.setGeometry(QtCore.QRect(110, 160, 75, 23)) self.calcbtn.setObjectName("calcbtn") ########################################################## self.calcbtn.clicked.connect(self.event) ######################################################### self.clrbtn = QtWidgets.QPushButton(self.centralwidget) self.clrbtn.setGeometry(QtCore.QRect(20, 160, 75, 23)) self.clrbtn.setObjectName("clrbtn") self.label = QtWidgets.QLabel(self.centralwidget) self.label.setGeometry(QtCore.QRect(20, 10, 81, 16)) self.label.setObjectName("label") MainWindow.setCentralWidget(self.centralwidget) self.retranslateUi(MainWindow) self.comboBox_1.setCurrentIndex(1) self.comboBox_2.setCurrentIndex(2) self.comboBox_3.setCurrentIndex(3) self.comboBox_ANS.setCurrentIndex(4) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "Mechanics")) self.comboBox.setItemText(0, _translate("MainWindow", "V")) self.comboBox.setItemText(1, _translate("MainWindow", "U")) self.comboBox.setItemText(2, _translate("MainWindow", "a")) self.comboBox.setItemText(3, _translate("MainWindow", "t")) self.comboBox.setItemText(4, _translate("MainWindow", "S")) self.comboBox_1.setItemText(0, _translate("MainWindow", "V")) self.comboBox_1.setItemText(1, _translate("MainWindow", "U")) self.comboBox_1.setItemText(2, _translate("MainWindow", "a")) self.comboBox_1.setItemText(3, _translate("MainWindow", "t")) self.comboBox_1.setItemText(4, _translate("MainWindow", "S")) self.comboBox_2.setItemText(0, _translate("MainWindow", "V")) self.comboBox_2.setItemText(1, _translate("MainWindow", "U")) self.comboBox_2.setItemText(2, _translate("MainWindow", "a")) self.comboBox_2.setItemText(3, _translate("MainWindow", "t")) self.comboBox_2.setItemText(4, _translate("MainWindow", "S")) self.comboBox_3.setItemText(0, _translate("MainWindow", "V")) self.comboBox_3.setItemText(1, _translate("MainWindow", "U")) self.comboBox_3.setItemText(2, _translate("MainWindow", "a")) self.comboBox_3.setItemText(3, _translate("MainWindow", "t")) self.comboBox_3.setItemText(4, _translate("MainWindow", "S")) self.comboBox_ANS.setItemText(0, _translate("MainWindow", "V")) self.comboBox_ANS.setItemText(1, _translate("MainWindow", "U")) self.comboBox_ANS.setItemText(2, _translate("MainWindow", "a")) self.comboBox_ANS.setItemText(3, _translate("MainWindow", "t")) self.comboBox_ANS.setItemText(4, _translate("MainWindow", "S")) self.calcbtn.setText(_translate("MainWindow", "SOLVE")) self.clrbtn.setText(_translate("MainWindow", "CLEAR")) self.label.setText(_translate("MainWindow", "MECHANICS")) if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) MainWindow = QtWidgets.QMainWindow() ui = Ui_MainWindow() ui.setupUi(MainWindow) MainWindow.show() sys.exit(app.exec_())
Поиск элементов в QComboBox
При вводе в поле, снизу будут появляться элементы, удовлетворяющие условиям поиска. Данные в combobox хранятся в модели, поиск по модели я сделать смогу, но возможно ли добавить некую строчку в сам QComboBox, которая будет выполнять функции поля для поиска, или же мне смотреть в какое-то другое русло? Я пока что понял, что можно добавить placeHolderText, но делая модель setEditable(true); , текст пропадает, а при изменении пустой строчки, сами элементы comboBox пропадают, и необходимо снова нажимать на стрелочку. Есть идеи?
Лучшие ответы ( 2 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
QComboBox — поиск элемента списка по введенной букве
Подскажите, пожалуйста, как можно в QComboBox сделать так, чтобы при вводе буквы с клавиатуры в.
QCombobox
Добрый день. Хочу реализовать добавление/изменение элемента БД с помощью дополнительного окна. как.
QComboBox
Всем привет. Можно ли сделать так, чтобы список (QComboBox) выпадал не вниз а вверх?
5006 / 4686 / 985
Регистрация: 11.10.2019
Сообщений: 12,251
PrOsTo_NiK_, глянь класс QCompleter
223 / 188 / 97
Регистрация: 15.04.2018
Сообщений: 718
Алексей1153, дополню, QCompleter + QLineEdit должны решить вашу проблему
Регистрация: 01.03.2022
Сообщений: 145
mvngr, Алексей1153, попробовал разобраться с QCompleter. Вряд ли нужный мне функционал возможно сделать с QLineEdit, учитывая, что при выборе элемента, мне нужно узнать его id из модели и позже удалить из базы данных.(если это возможно — подскажите как), поэтому делал с QComboBox(т.к. там есть сигнал on_comboBox__activated(int index), но есть несколько проблем и вопросов:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
comp_assi = new QSortFilterProxyModel(this); comp_assi->setSourceModel(assignment_contacts); comp_assi->setFilterCaseSensitivity(Qt::CaseInsensitive); comp_assi->setFilterKeyColumn(1); ui->comboBox_NewClientContacts->setModel(assignment_contacts); ui->comboBox_NewClientContacts->setModelColumn(1); completer = new QCompleter(this); completer->setCaseSensitivity(Qt::CaseInsensitive); completer->setModel(comp_assi); completer->setCompletionColumn(1); completer->setCompletionMode(QCompleter::PopupCompletion); ui->comboBox_NewClientContacts->setCompleter(completer);
При таком написании, в целом, функционал работает,
Но выбрав элемент в этом списке, он зачем-то появляется в строчке, в которой до этого выполнялся поиск:
И я никак не пойму, как мне обратиться к этой строчке, чтобы её очистить. К тому же, обратиться к этой строчке нужно еще для такого функционала, как, например, «Подсказка», чтобы там всегда было слово «Выбрать. «, но когда она получает фокус, чтобы текст пропадал.
223 / 188 / 97
Регистрация: 15.04.2018
Сообщений: 718
QCompleter — как подсказка при поиске в браузере. Она дополняет то, что вы уже ввели
В вашем случае можно:
а) действительно всё сделать на комбобоксе
б) использовать QCompleter вместе с QLineEdit для более удобного набора. А после следить за каким-нибудь editingFinished, по его срабатыванию проверять, существует ли такая запись у вас в модели. Если существует — попросту удять данные из бд.
Т.е. у вас цепочка YourModel + QCompleter + QLineEdit при срабатывании editingFinished у YourModel смотрим, существует ли такая запись. При существовании лезем в бд и делаем ваши действия
Регистрация: 01.03.2022
Сообщений: 145
mvngr, Если использовать QLineEdit, то все данные, которые можно иметь — это то, что пользователь ввёл в этот LineEdit, без просмотра содержимого модели, верно? Вы предлагаете лишь потом проверять, существует ли такая запись в модели. А если в этой модели два человека с абсолютно одинаковыми ФИО? Выбрав элемент Иванов А.А. из БД удалятся все Ивановы А.А, а не тот, что именно выбрал пользователь, разве нет?
223 / 188 / 97
Регистрация: 15.04.2018
Сообщений: 718
PrOsTo_NiK_, да, но по вашей же логике пользователь видит двух Ивановых, а хочет он удалить конкретного. Доп информации при вводе ФИО (например id) он ведь не видит
Добавлено через 1 минуту
мне кажется лучше тогда сделать выбор пользователя с отображением всей его инфы, а уже в углу кнопка удаления
А поиск этого пользователя уже можно сделать на основе qcompleter или qcombobox
Регистрация: 01.03.2022
Сообщений: 145
mvngr, По сути говоря, тут реализован функционал добавления контакта к компании, то есть нажимаешь, и данный контакт добавляется к выбранной компании. И он же добавляется в таблицу в БД, в которой два поля — id компании и id контакта. Выбирая между тем, чтобы добавить случайно не того контакта / добавить ВСЕХ контактов с таким ФИО — предпочтительно первый вариант. Ибо контактов с одним ФИО может быть множество, и будет не совсем корректно это выглядеть)
223 / 188 / 97
Регистрация: 15.04.2018
Сообщений: 718
PrOsTo_NiK_, как мы выяснили, ФИО не является уникальным ключом. Если есть — используйте логин при добавлении в компанию, проблема пропадет сама собой
А QCompleter я считаю удобной штукой, которую стоит освоить
Регистрация: 01.03.2022
Сообщений: 145
В этом и суть, что я выбрал использование QComboBox из-за возможности обращаться к её модели. При том написании, что я указывал выше, всё работает, ты нажимаешь на ФИО, происходит добавление нужного контакта в БД.
1 2 3 4 5 6 7 8 9 10 11 12
void MainWindow::on_comboBox_NewClientContacts_activated(int index) { database::AddAssignment(QString::number(nextId), assignment_contacts->data(assignment_contacts->index(index,0),Qt::DisplayRole).toString()); UpdateClientContacts(nextId, 1); QSqlQuery query; query.prepare("SELECT id, fullName FROM contacts WHERE contacts.rowid NOT IN (SELECT contactId FROM assignment WHERE companyId = :nextId);"); query.bindValue(":nextId", nextId); query.exec(); assignment_contacts->setQuery(std::move(query)); ui->comboBox_NewClientContacts->setModel(assignment_contacts); ui->comboBox_NewClientContacts->setModelColumn(1); }
В целом, это хоть и коряво, но работает, проблема опять же в том, что я написал в самом вопросе — в строчке. Я понимаю, что буквально, комплитер мне дополнил строчку, но нажав на popup, который выдал комплитер, происходит обработка выше указанного сигнала, что мне и нужно. Вопрос в том, можно ли после этого эту строчку каким-то образом стереть, чтобы поиск начинался по новой? Надеюсь, Вы поняли, о чём я
QLineEdit with Custom QComboBox
Hi guys i am pretty new to Qt and now trying to make a simple dictionary application and i wanted to customize the QLineEdit with QComboBox inside like u get a search box with magnifier icon and down arrow right next to it and u can choose from the options right inside the QLineEdit. The idea seems easy to realize as i inherited QLineEdit and used a new QComboBox inside and i managed to get QComboBox inside the QLine edit with magnifier or any icons but the problem is the down arrow of QComboBox cant be set closer to the icons like almost overlaps little bit from left small down arrow i tries different styleSheet stuffs but still the distance between down arrow and the icon is not changed. Any suggestions will be appreciated..
goetz отредактировано
I don’t know exactly what you want, but could a editable QComboBox be a solution for you? Another guess might be to use the input widget in the locator of Qt Creator. I don’t know if it is available as a more or less standalone widget.
mohsen отредактировано
@Volker: I guess he needs an autofill textbox. you could use same combobox and make it appear like textbox using style http://developer.qt.nokia.com/forums/viewthread/3150 then you can design a combo box with your theme by placing a button to expand combo box where ever you want.
bahonurn отредактировано
thanks for the replies but the thing is i want like a input box with icon and down arrow before the input itself where one can click the arrow next to the icon and choose different options to search like hmm english or other alternative languages
giesbert отредактировано
Can you show us a picture, of what you want to achieve? that would make it clearer.
Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)
bahonurn отредактировано
Here i am attaching the link where it shows a simple iTunes search box. As u see it has magnifier glass with drop down options to search. So that is almost what i want to do if that is realizable in Qt. Thanks Guys :)!http://lifehacker.com/246006/add-search-keyboard-shortcut-to-itunes-on-your-mac()!
goetz отредактировано
This is what Qt Creator uses in its locator on the bottom. Maybe it’s not too hard to extract it from its sources.
Урок №10. Виджеты в Qt5
Виджеты в Qt5 — это «строительные блоки» для создания пользовательского интерфейса. Визуальные объекты на форме, такие как кнопки, метки, поля, меню, раскрывающиеся списки и т.д. — всё это относится к виджетам.
На этом уроке мы рассмотрим следующие виджеты в Qt5:
Оглавление:
- Виджет QLabel
- Виджет QSlider
- Виджет QComboBox
- Виджет QSpinBox
- Виджет QLineEdit
- Строка состояния
- Заключение
Виджет QLabel
Виджет QLabel используется для отображения текста или изображения. При этом стоит отметить, что у него не предусмотрено взаимодействие с пользователем. В следующем примере мы задействуем данный виджет для отображения в окне текстов песен.
Заголовочный файл — label.h:
#pragma once
class Label : public QWidget <
Label ( QWidget * parent = 0 ) ;
QLabel * label ;
Файл реализации — label.cpp:
#include «label.h»
Label :: Label ( QWidget * parent )
: QWidget ( parent ) <
QString lyrics = "Who doesn't long for someone to hold\n\
Who knows how to love you without being told\n\
Somebody tell me why I'm on my own\n\
If there's a soulmate for everyone\n\
Here we are again, circles never end\n\
How do I find the perfect fit\n\
There's enough for everyone\n\
But I'm still waiting in line\n\
Who doesn't long for someone to hold\n\
Who knows how to love you without being told\n\
Somebody tell me why I'm on my own\n\
If there's a soulmate for everyone" ;
label = new QLabel ( lyrics , this ) ;
label -> setFont ( QFont ( «Purisa» , 10 ) ) ;
QVBoxLayout * vbox = new QVBoxLayout ( ) ;
vbox -> addWidget ( label ) ;
setLayout ( vbox ) ;
Создаем виджет метки и устанавливаем для него определенный шрифт:
label = new QLabel ( lyrics , this ) ;
label -> setFont ( QFont ( «Purisa» , 10 ) ) ;
Основной файл программы — main.cpp:
#include «label.h»
int main ( int argc , char * argv [ ] ) <
QApplication app ( argc , argv ) ;
Label window ;
window . setWindowTitle ( "QLabel" ) ;
window . show ( ) ;
return app . exec ( ) ;
Результат выполнения программы:
Виджет QSlider
Виджет QSlider представляет собой вертикальный или горизонтальный ползунок (слайдер). Он позволяет пользователю перемещать маркер ползунка вдоль горизонтальной или вертикальной линии и переводит положение ползунка в целочисленное значение в пределах допустимого диапазона.
В следующем примере у нас есть два виджета: слайдер и метка. Ползунок будет управлять числом, отображаемым в метке.
Заголовочный файл — slider.h:
#pragma once
class Slider : public QWidget <
Slider ( QWidget * parent = 0 ) ;
QSlider * slider ;
QLabel * label ;
Файл реализации — slider.cpp:
#include «slider.h»
Slider :: Slider ( QWidget * parent )
: QWidget ( parent ) <
QHBoxLayout * hbox = new QHBoxLayout ( this ) ;
slider = new QSlider ( Qt :: Horizontal , this ) ;
hbox -> addWidget ( slider ) ;
label = new QLabel ( «0» , this ) ;
hbox -> addWidget ( label ) ;
connect ( slider , &QSlider :: valueChanged , label ,
static_cast < void ( QLabel :: * ) ( int ) >( &QLabel :: setNum ) ) ;
Создаем горизонтальный QSlider :
slider = new QSlider ( Qt :: Horizontal , this ) ;
Далее подключаем сигнал valueChanged() к встроенному в метку слоту setNum(). Поскольку метод setNum() перегружен, то мы используем оператор static_cast для выбора корректного метода:
connect ( slider , &QSlider :: valueChanged , label ,
static_cast < void ( QLabel :: * ) ( int ) >( &QLabel :: setNum ) ) ;
Основной файл программы — main.cpp:
#include «slider.h»
int main ( int argc , char * argv [ ] ) <
QApplication app ( argc , argv ) ;
Slider window ;
window . setWindowTitle ( "QSlider" ) ;
window . show ( ) ;
return app . exec ( ) ;
Результат выполнения программы:
Виджет QComboBox
QComboBox — это виджет выбора, который отображает текущий элемент и может отображать выпадающий список выбираемых элементов. Список при этом может быть редактируемым, позволяя пользователю изменять каждый элемент в данном списке.
В следующем примере выбранный элемент из QComboBox будет отображаться в метке.
Заголовочный файл — combobox.h:
#pragma once
class ComboBoxEx : public QWidget <
ComboBoxEx ( QWidget * parent = 0 ) ;
QComboBox * combo ;
QLabel * label ;
Файл реализации — combobox.cpp:
#include «combobox.h»
ComboBoxEx :: ComboBoxEx ( QWidget * parent )
: QWidget ( parent ) <
QStringList distros = < "Arch" , "Xubuntu" , "Redhat" , "Debian" ,
QHBoxLayout * hbox = new QHBoxLayout ( this ) ;
combo = new QComboBox ( ) ;
combo -> addItems ( distros ) ;
hbox -> addWidget ( combo ) ;
hbox -> addSpacing ( 15 ) ;
label = new QLabel ( «Arch» , this ) ;
hbox -> addWidget ( label ) ;
connect ( combo , static_cast < void ( QComboBox :: * ) ( const QString & ) >( &QComboBox :: activated ) ,
В QStringList хранятся данные QComboBox , а именно список названий дистрибутивов Linux:
QStringList distros = < "Arch" , "Xubuntu" , "Redhat" , "Debian" ,
Создаем QComboBox , а затем с помощью метода addItems() добавляем в него элементы:
combo = new QComboBox ( ) ;
combo -> addItems ( distros ) ;
Сигнал activated() нашего QComboBox подключается к слоту setText() метки. Поскольку сигнал перегружен, то мы делаем статическое преобразование данных при помощи оператора static_cast:
connect ( combo , static_cast < void ( QComboBox :: * ) ( const QString & ) >( &QComboBox :: activated ) ,
Основной файл программы — main.cpp:
#include «combobox.h»
int main ( int argc , char * argv [ ] ) <
QApplication app ( argc , argv ) ;
ComboBoxEx window ;
window . resize ( 300 , 150 ) ;
window . setWindowTitle ( "QComboBox" ) ;
window . show ( ) ;
return app . exec ( ) ;
Результат выполнения программы:
Виджет QSpinBox
QSpinBox — это виджет, который используется для обработки целых чисел и дискретных наборов значений. Данный виджет позволяет пользователю указать нужное значение либо вручную, либо кликая мышкой по кнопкам вверх/вниз, либо нажимая клавиши клавиатуры вверх/вниз для увеличения/уменьшения значения, отображаемого в текущий момент.
В следующей программе с помощью виджета QSpinBox мы можем выбирать число от 0 до 99. Выбранное в текущий момент значение отображается в метке.
Заголовочный файл — spinbox.h:
#pragma once
class SpinBox : public QWidget <
SpinBox ( QWidget * parent = 0 ) ;
QSpinBox * spinbox ;
Файл реализации — spinbox.cpp:
#include «spinbox.h»
SpinBox :: SpinBox ( QWidget * parent )
: QWidget ( parent ) <
QHBoxLayout * hbox = new QHBoxLayout ( this ) ;
hbox -> setSpacing ( 15 ) ;
spinbox = new QSpinBox ( this ) ;
QLabel * lbl = new QLabel ( «0» , this ) ;
hbox -> addWidget ( spinbox ) ;
hbox -> addWidget ( lbl ) ;
connect ( spinbox , static_cast < void ( QSpinBox :: * ) ( int ) >( &QSpinBox :: valueChanged ) ,
lbl , static_cast < void ( QLabel :: * ) ( int ) >( &QLabel :: setNum ) ) ;
Нам нужно выполнить конвертацию с помощью оператора static_cast дважды, потому что и сигнал, и слот перегружены:
connect ( spinbox , static_cast < void ( QSpinBox :: * ) ( int ) >( &QSpinBox :: valueChanged ) ,
lbl , static_cast < void ( QLabel :: * ) ( int ) >( &QLabel :: setNum ) ) ;
Основной файл программы — main.cpp:
#include «spinbox.h»
int main ( int argc , char * argv [ ] ) <
QApplication app ( argc , argv ) ;
SpinBox window ;
window . resize ( 250 , 150 ) ;
window . setWindowTitle ( "QSpinBox" ) ;
window . show ( ) ;
return app . exec ( ) ;
Результат выполнения программы:
Виджет QLineEdit
Виджет QLineEdit представляет собой редактор однострочного текста. Редактор строки позволяет пользователю вводить одну строку обычного текста и при этом использовать такие функции редактирования, как: отмена, повтор, вырезание, вставка, а также перетаскивание с помощью механизма drag-and-drop.
В следующем примере мы выведем три метки и три строки для редактирования, которые скомпонованы с помощью менеджера компоновки QGridLayout.
Заголовочный файл — ledit.h:
#pragma once
class Ledit : public QWidget <
Ledit ( QWidget * parent = 0 ) ;
Файл реализации — ledit.cpp:
#include «ledit.h»
Ledit :: Ledit ( QWidget * parent )
: QWidget ( parent ) <
QLabel * name = new QLabel ( "Name:" , this ) ;
name -> setAlignment ( Qt :: AlignRight | Qt :: AlignVCenter ) ;
QLabel * age = new QLabel ( «Age:» , this ) ;
age -> setAlignment ( Qt :: AlignRight | Qt :: AlignVCenter ) ;
QLabel * occupation = new QLabel ( «Occupation:» , this ) ;
occupation -> setAlignment ( Qt :: AlignRight | Qt :: AlignVCenter ) ;
QLineEdit * le1 = new QLineEdit ( this ) ;
QLineEdit * le2 = new QLineEdit ( this ) ;
QLineEdit * le3 = new QLineEdit ( this ) ;
QGridLayout * grid = new QGridLayout ( ) ;
grid -> addWidget ( name , 0 , 0 ) ;
grid -> addWidget ( le1 , 0 , 1 ) ;
grid -> addWidget ( age , 1 , 0 ) ;
grid -> addWidget ( le2 , 1 , 1 ) ;
grid -> addWidget ( occupation , 2 , 0 ) ;
grid -> addWidget ( le3 , 2 , 1 ) ;
setLayout ( grid ) ;
Основной файл программы — main.cpp:
#include «ledit.h»
int main ( int argc , char * argv [ ] ) <
QApplication app ( argc , argv ) ;
Ledit window ;
window . setWindowTitle ( "QLineEdit" ) ;
window . show ( ) ;
return app . exec ( ) ;
Результат выполнения программы:
Строка состояния
Строка состояния (англ. «statusbar») — это панель, которая используется для отображения информации о состоянии приложения. Виджет Statusbar является частью виджета QMainWindow .
В следующем примере у нас есть две кнопки и одна строка состояния. При нажатии на кнопку будет отображаться соответствующее сообщение.
Заголовочный файл — statusbar.h:
#pragma once
class Statusbar : public QMainWindow <
Statusbar ( QWidget * parent = 0 ) ;
private slots :
void OnOkPressed ( ) ;
void OnApplyPressed ( ) ;
QPushButton * okBtn ;
QPushButton * aplBtn ;
Файл реализации — statusbar.cpp:
#include «statusbar.h»
Statusbar :: Statusbar ( QWidget * parent )
: QMainWindow ( parent ) <
QFrame * frame = new QFrame ( this ) ;
setCentralWidget ( frame ) ;
QHBoxLayout * hbox = new QHBoxLayout ( frame ) ;
okBtn = new QPushButton ( "OK" , frame ) ;
hbox -> addWidget ( okBtn , 0 , Qt :: AlignLeft | Qt :: AlignTop ) ;
aplBtn = new QPushButton ( «Apply» , frame ) ;
hbox -> addWidget ( aplBtn , 1 , Qt :: AlignLeft | Qt :: AlignTop ) ;
connect ( okBtn , &QPushButton :: clicked , this , &Statusbar :: OnOkPressed ) ;
connect ( aplBtn , &QPushButton :: clicked , this , &Statusbar :: OnApplyPressed ) ;
void Statusbar :: OnOkPressed ( ) <
statusBar ( ) -> showMessage ( «OK button pressed» , 2000 ) ;
void Statusbar :: OnApplyPressed ( ) <
statusBar ( ) -> showMessage ( «Apply button pressed» , 2000 ) ;
Виджет QFrame помещается в центральную область виджета QMainWindow . Центральную область может занимать только один виджет:
QFrame * frame = new QFrame ( this ) ;
setCentralWidget ( frame ) ;
Мы создаем два виджета QPushButton и компонуем их вдоль горизонтальной линии. Родительским элементом кнопок является виджет frame :
okBtn = new QPushButton ( «OK» , frame ) ;
hbox -> addWidget ( okBtn , 0 , Qt :: AlignLeft | Qt :: AlignTop ) ;
aplBtn = new QPushButton ( «Apply» , frame ) ;
hbox -> addWidget ( aplBtn , 1 , Qt :: AlignLeft | Qt :: AlignTop ) ;
Для отображения строки состояния мы вызываем метод statusBar() виджета QMainWindow :
Метод showMessage() отображает сообщение в строке состояния. Последний параметр указывает количество миллисекунд, в течение которых сообщение отображается в строке состояния:
void Statusbar :: OnOkPressed ( ) < statusBar ( ) -> showMessage ( «OK button pressed» , 2000 ) ;
Основной файл программы — main.cpp:
#include «statusbar.h»
int main ( int argc , char * argv [ ] ) <
QApplication app ( argc , argv ) ;
Statusbar window ;
window . resize ( 300 , 200 ) ;
window . setWindowTitle ( "QStatusBar" ) ;
window . show ( ) ;
return app . exec ( ) ;
Результат выполнения программы:
Заключение
Как вы уже могли заметить, виджеты являются простым, но в то же время довольно мощным инструментом построения графической части приложений, созданных при помощи Qt5. На следующем уроке мы продолжим тему виджетов.
(39 оценок, среднее: 4,69 из 5)
Урок №9. Слоты, Сигналы и События в Qt5
Урок №11. Виджеты в Qt5 (продолжение)
Комментариев: 15
Для пользователей Qt6:
В QComboBox сигнал activated больше не является перегруженным, он имеет только одну версию, возвращающую из параметров только тип int:
void QComboBox :: activated ( int index )
Для корректной работы примера из урока можно использовать сигналы:
void QComboBox :: currentTextChanged ( const QString & text )
void QComboBox :: textActivated ( const QString & text )
Разница между ними в том, что первый будет генерировать сигнал только когда вы изменили значение ComboBox, а второй если вы выбрали даже то же самое значение, которое было установлено. На данном примере эта разница заметна не будет, но нужно иметь ее ввиду при создании приложений. P.S. Спасибо автору и сайту за отличные уроки.
Приветствую! Не могу понять, что есть userData = QVariant().
Возможно ли хранит нужные пользовательские данные в элементе меню QComboBox?
Добавляю AddItem func(text string, userData core.QVariant_ITF), все отображается.
Но вот незадача: нужно при выборе элемента меню получать ID (НЕ ИНДЕКС) этого элемента, который я хочу хранить в userData.
Ситуация следующая: есть список городов из openweather:
«id» : 8224454 ,
«name» : «Novyi Svit» ,
«country» : «UA» ,
«lon» : 34.91301 ,
«lat» : 44.82988
В QComboBox я добавляю список из городов и стран : Novyi Svit UA.
При сигнале activated на Novyi Svit UA нужно получать 8224454.
Добрый день.
Подскажите для чего делать преобразование:
connect ( combo , static_cast < void ( QComboBox :: * ) ( const QString & ) >( & QComboBox :: textActivated ) , lbl , & QLabel :: setText ) ;
если можно сделать так:
connect ( combo , & QComboBox :: textActivated , lbl , & QLabel :: setText ) ;
Дмитрий Бушуев :
>>Подскажите для чего делать преобразование […] QComboBox::textActivated […] Я не вижу в статье такого преобразования. А вот преобразование для QComboBox::activated — вижу. Выполняется оно вот для чего (опять-таки, цитата из статьи): «Сигнал activated() нашего QComboBox подключается к слоту setText() метки. Поскольку сигнал перегружен, то мы делаем статическое преобразование данных при помощи оператора static_cast: connect(combo, static_cast
label, &QLabel::setText);
«
Вам не нравится замена устаревшего в Вашем примере &QComboBox::activated на textActivated это Вас смутило ? Так QT указывает, что Ваш пример устарел и рекомендует его поменять на textActivated. Но по существу на вопрос Вы так и не ответили, ответьте пожалуйста на вопрос.
Дмитрий Бушуев :
Юрий :
Ваши комментарии удаляю я. На ваш вопрос ответили и все ваши последующие комментарии, которые не несут в себе ни сути, ни пользы — будут удалены.
Для примера «Виджет QComboBox», в файле combobox.cpp не прошла «Сборка -> Запустить». Строки
QStringList distros = < "Arch" , "Xubuntu" , "Redhat" , "Debian" ,
пришлось заменить на
QStringList distros ;
distros << "Arch" << "Xubuntu" << "Redhat" << "Debian" << "Mandriva" ;
и тогда все получилось.
Спасибо за Ваши материалы!
Здравствуйте , подскажите пожалуйста по поводу перегруженных сигналов и слотов.
Насколько я понял из документации сейчас предпочтительнее использовать QOverload?
Так же не совсем понятно, почему мы приводим к указателю на функцию?
Сигнал подключается к указателю на функцию и мы передаём указатель слоту?
Запутался, помогите)
Теперь, кажется, понял.
Видим, что нам нужен SetNum >>>>> смотрим его в документации и видим, что есть 2 варианта in и double а нам нужен int. Просто сама запись static_cast как-то ускользает. Понятно, когда вот так:
int i = 49;
char ch = static_cast(i);
А тут преобразовать в указатель на функцию..
Добрый день!
В примере с виджетом QSlider
в файле slider.cpp
нехватает мозга понять последнюю строку несмотря на разъяснения.
connect ( slider , & QSlider :: valueChanged , label , static_cast < void ( QLabel :: * ) ( int ) >( & QLabel :: setNum ) ) ;
отправитель, сигнал,получатель, и вот последний параметр в коннект
static_cast(&QLabel::setNum) что он делает?
Преобразует в «void (QLabel::*)(int)» значение «(&QLabel::setNum)»
Т.е. сам static_cast тут непонятен..
Дмитрий Бушуев :
Добрый!
Смотрите, в самой статье уже идет подсказка:
>»Поскольку метод setNum() перегружен, мы используем оператор static_cast для выбора корректного метода» …ага, если метод перегружен, значит есть и другие? Тогда идем в оф. доки по Qt, смотрим описание класса QLabel (https://doc.qt.io/qt-5/qlabel.html) и видим там две функции setNum():
>void setNum(double num)
>void setNum(int num) …теперь возвращаемся к строчке с «connect…». Как она работает? Да очень просто — она связывает источник сигнала — slider, сам сигнал — &QSlider::valueChanged, приемник сигнала — label и метод, которым этот сигнала будет обработан (т.е. слот) — функция setNum()…. эмм… а…. а у нас же их две, какая из них должна вызываться? Вот чтобы явно указать, что нам нужен вот такой вариант функции — setNum(int num) — мы и используем вариант приведения к функции void (QLabel::*)(int) через static_cast. Ведь что такое — void (QLabel::*)(int)? Это указатель на функцию-элемент класса QLabel, которая принимает в качестве аргумента одну переменную типа int и возвращает void. А такому прототипу соответствует только функция void QLabel::setNum(int num). Тем самым мы ясно дали понять, что хотим использовать в качестве слота (или по-простому — обработчика события) именно её, а не похожую функцию void setNum(double num).
Добрый день. Можете дать ссылку, где в С++ рассказывается про подобное применение static_cast<>? Хотелось бы подробнее вникнуть.