I'm new to programming and using qt to create my own GUI. I'm trying to make a search bar one of my list view's but it keeps saying that there is no matching function to call... This may be a really stupid question. Here is my code.
void Widget::on_SearchBar_textChanged(const QString &arg1)
{
QString Input;
ui->Online->find(Input);
}
and the error
C:\Qt\Qt5.1.1\Tools\QtCreator\bin\CryptoCourier\widget.cpp:21: error: no matching function for call to 'QListWidget::find(QString&)'
ui->Online->find(Input);
here is the rest of my code as requested
Ok So here is the rest of my code. Not much but here.
#include "widget.h"
#include "ui_CryptoCC.h"
#include <QString>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_SearchBar_textChanged(const QString &arg1)
{
#include <string>
QString Input;
ui->Online->find(Input);
}
^
You have two major problems:
#include statements should go outside of functions, since they literally include an entire file exactly where you put them.
For QString, the file you want to include is probably called "QString".
Try something like this:
#include <QString>
/* the rest of your code, which you didn't include in your example */
void Widget::on_SearchBar_textChanged(const QString &arg1)
{
/* by the way, you're calling Online->find() with an empty string,
* did you mean to use `arg1` here? */
QString Input;
ui->Online->find(Input);
}
Beyond that, I'd need to know what ui and ui->Online are before I could give you advice about what functions you can call on them.
Related
I'm new to any form of programming but have to do a project with Qt for my "programming for engineers" course where we simultaneously learn the basics of c++.
I have to display a text from one lineEdit to a lineEdit in another window.
I have a userWindow that opens from the mainWindow and in this userWindow I have a lineEdit widget that displays the current selected user as a QString (from a QDir object with .dirName() ). But now I have to display the same String in a lineEdit in the mainWindow as well.
From what I've read I have to do this with "connect(...)" which I have done before with widgets inside a single .cpp file but now I need to connect a ui object and signal from one window to another and I'm struggling.
My idea /what I could find in the internet was this:
userWindow.cpp
#include "userwindow.h"
#include "ui_userwindow.h"
#include "mainwindow.h"
#include <QDir>
#include <QMessageBox>
#include <QFileDialog>
#include <QFileInfo>
QDir workingUser; //this is the current selected user. I tried defining it in userWindow.h but that wouldn't work how I needed it to but that's a different issue
userWindow::userWindow(QWidget *parent) : //konstruktor
QDialog(parent),
ui(new Ui::userWindow)
{
ui->setupUi(this);
QObject::connect(ui->outLineEdit, SIGNAL(textChanged()), mainWindow, SLOT(changeText(workingUser) //I get the error " 'mainWIndow' does not refer to a value "
}
[...]
mainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QDir>
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
public slots:
void changeText(QDir user); //this is the declaration of my custom SLOT (so the relevant bit)
private slots:
void on_userButton_clicked();
void on_settingsButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "userwindow.h"
#include "settingswindow.h"
#include "click_test_target.h"
#include "random_number_generator.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
[...]
}
[...]
//here I define the slot
void MainWindow::changeText(QDir user)
{
QString current = user.dirName();
ui->userLine->insert("The current working directory is: "); //"userLine" is the lineEdit I want to write the text to
ui->userLine->insert(current);
}
I know I'm doing something wrong with the object for the SLOT but can't figure out how to do it correctly.
If anyone could help me I would be very grateful.
Alternatively: perhaps there is another way to mirror the text from one lineEdit to another over multiple windows. If anybody could share a way to do this I would be equally grateful. Is there maybe a way to somehow define the variable "QDir workingUser;" in such a way as to be able to access and overwrite it in all of my .cpp files?
Thank you in advance for any help. Regards,
Alexander M.
"I get the error 'mainWindow' does not refer to a value"
I don't see you having any "mainWindow" named variable anywhere,
but you also mentioned that the MainWindow is the parent, which means you could get reference anytime, like:
MainWindow *mainWindow = qobject_cast<MainWindow *>(this->parent());
Also, your signal-handler (changeText(...) slot) should take QString as parameter (instead of QDir), this way you handle how exactly the conversion is handled, in case users type some random text in input-field (text-edit).
void changeText(const QString &input);
Finally, you either need to specify type:
QObject::connect(ui->outLineEdit, SIGNAL(textChanged(QString)), mainWindow, SLOT(changeText(QString));
Or, use the new Qt-5 syntax:
connect(ui->outLineEdit, &QLineEdit::textChanged,
mainWindow, &MainWindow::changeText);
You can create new signal (same params as lineEdit's textChanged) to userWindow which is connected to the textChanged signal of the lineEdit. Then connect that signal userWindow to mainWindow's slot.
//In userWindow.h
signals:
void textChanged(const QString&);
//In userWindow.cpp
connect(ui.lineEdit, &QLineEdit::textChanged, this, &userWindow::textChanged);
//In mainWindow.cpp
connect(userWindow, &userWindow::textChanged, this, &mainWindow::onTextChanged
Then in onTextChanged write the same text to mainWindow's lineEdit
I have a Qt gui project and in the "mainwindow.cpp" file I have to define a function that I cannot declare under "mainwindow.h". But I want to call that function (func_sqrt) under MainWindow and show the result value of my func_sqrt in a label. For some reason I need to do that so. But I don't know how to connect that function to the gui objects. My code looks like this:
#include "mainwindow.h"
#include "ui_mainwindow.h"
QString input;
void func_sqrt(int x);
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
func_sqrt(2);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::showtext(QString txt)
{
ui->lbl_value->setText(txt);
}
void func_sqrt(int x)
{
int y;
y = x*x;
}
I added this part to the func_sqrt function, but it doesn't work:
MainWindow *w = new MainWindow;
w->showtext(QString::number(y));
First of all, your func_sqrt currently is a no-op. Next, internally it calculates a square yet its name says sqrt (short for square root), you might want to check whether the name is consistent with semantics. This is for the side notes.
If you need this function available outside of mainwindow.cpp, you can declare it in a separate header and include it everywhere as needed. Alternatively, you can declare it in every file it is used in, the linker will later resolve the actual implementation. For instance, in a file subordinatewindow.cpp:
void func_sqrt(int);
// ...
int x{42};
func_sqrt(x);
I was trying the QFileSystemWatcher out and it somehow doesn't work as expected. Or am I doing something wrong?
I've set the QFileSystemWatcher to watch a single file. When I modify the file for the first time, fileChanged() gets emited, that's OK. But when I modify the file again, fileChanged() doesn't get emited anymore.
Here is the source code:
main.cpp
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
mainwindow.h
#include <QDebug>
#include <QFileSystemWatcher>
#include <QMainWindow>
#include <QString>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow();
private slots:
void directoryChanged(const QString & path);
void fileChanged(const QString & path);
private:
QFileSystemWatcher * watcher;
};
mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow()
{
watcher = new QFileSystemWatcher(this);
connect(watcher, SIGNAL(fileChanged(const QString &)), this, SLOT(fileChanged(const QString &)));
connect(watcher, SIGNAL(directoryChanged(const QString &)), this, SLOT(directoryChanged(const QString &)));
watcher->addPath("path to directory");
watcher->addPath("path to file");
}
void MainWindow::directoryChanged(const QString & path)
{
qDebug() << path;
}
void MainWindow::fileChanged(const QString & path)
{
qDebug() << path;
}
Thank you for your answers.
Edit 1
I ran this code under Linux.
Edit 2
I actually need to check all MetaPost files in a tree given by some directory, whether they were modified. I will probably stick to my alternative solution, which is to run QTimer every second and manually check all files. The QFileSystemWatcher probably does this in similar fashion internally, but probably more effectively.
Had the same problem just now. Seems like QFileSystemWatcher thinks that the file is deleted even if it's only modified. Well at least on Linux file system. My simple solution was:
if (QFile::exists(path)) {
watcher->addPath(path);
}
Add the above to your handler of fileChanged(). Change the word watcher as necessary.
I had the same problem using Qt5 on Linux. Found out the reason :
Some text editors, like kate, don't modify the contents of a file, but replace the original file with a new file. Replacing a file will delete the old one (IN_DELETE_SELF event), so qt will stop watching the file.
A solution is to also watch the file's directory for creation events.
I can confirm your problem with current Qt5 and Linux.
In addition to the answer given by Peter I solved this problem by adding the following code to the end of the slot-function:
QFileInfo checkFile(path);
while(!checkFile.exists())
std::this_thread::sleep_for(std::chrono::milliseconds(10));
watcher->addPath(path);
Note that if you add the path immediately, the file often does not exist yet, you get a warning and nothing will be added at all and the watcher looses this path. Therefore, you have to wait/sleep until the file is back to life again, then add it.
Also note that in this example I used C++11 and included and for realizing the sleep.
I keep getting this error:
cannot call member function 'QString Load::loadRoundsPlayed()'without object
Now im pretty new to c++ and qt so im not sure what this means. I am trying to call a function from another class to set the number on some lcdNumbers. Here is the Load.cpp which holds the function:
#include "load.h"
#include <QtCore>
#include <QFile>
#include <QDebug>
Load::Load() //here and down
{}
QString Load::loadRoundsPlayed()
{
QFile roundsFile(":/StartupFiles/average_rounds.dat");
if(!roundsFile.open(QFile::ReadOnly | QFile::Text))
{
qDebug("Could not open average_rounds for reading");
}
Load::roundsPlayed = roundsFile.readAll();
roundsFile.close();
return Load::roundsPlayed;
}
And here is the Load.h:
#ifndef LOAD_H
#define LOAD_H
#include <QtCore>
class Load
{
private:
QString roundsPlayed; //and here
public:
Load();
QString loadRoundsPlayed(); //and here
};
#endif // LOAD_H
And finally the place where i call the function:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "load.h"
#include <QLCDNumber>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
MainWindow::startupLoad();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::startupLoad()
{
ui->roundPlayer_lcdNumber->display(Load::loadRoundsPlayed()); //right here
}
When i run this i get that error. Im not sure what it means so if anyone could help i would be thankfull. Thanks.
The error description is pretty clear
cannot call member function 'QString Load::loadRoundsPlayed()'without object
You cannot call member functions, that are not static, without creating instance of the class.
Looking at you code, you probably need to do this:
Load load;
ui->roundPlayer_lcdNumber->display(load.loadRoundsPlayed()); //right here
There are two other options:
make loadRoundsPlayed static and roundsPlayed static, if you don't want them to be associated with the concrete instances OR
make loadRoundsPlayed static and return QString by copy, that will be locally created inside the function. Something like
:
QString Load::loadRoundsPlayed()
{
QFile roundsFile(":/StartupFiles/average_rounds.dat");
if(!roundsFile.open(QFile::ReadOnly | QFile::Text))
{
qDebug("Could not open average_rounds for reading");
}
QString lRoundsPlayed = roundsFile.readAll();
roundsFile.close();
return lRoundsPlayed;
}
Because the method and member are not associated with class instances, make it static:
class Load
{
private:
static QString roundsPlayed;
public:
Load();
static QString loadRoundsPlayed();
};
If you want them to be associated with instances, you'll need to create an object and call the method on it (it doesn't have to be static in this case).
In Load::loadRoundsPlayed(), you should change
Load::roundsPlayed = roundsFile.readAll();
to
this->roundsPlayed = roundsFile.readAll();
or simply
roundsPlayed = roundsFile.readAll();
This particular example won't fix the compiler error, but it illustrates where you are having some confusion with the syntax. When you prefix a function or variable name with "Load::", you are saying that you want the field that belongs to this class. However, every object of a class will have its own copy of the variables that you have declared in it. This means that you need to create an object before you can use them. Similarly, functions are bound to objects, so you again need an object in order to call a member function.
The other option is to make your functions static so that you don't need an object to call it. I strongly encourage you to learn about the difference between instance functions and static functions of a class so that you can use these two tools appropriately when the situation calls for it.
Class with the information that should trigger the the search then display of the other classes after connecting using signal and slots:
#include "recruitsearch.h"
#include "ui_recruitsearch.h"
#include <cctype>
#include <QtGui>
#include <string>
#include <QtCore>
using namespace std;
RecruitSearch::RecruitSearch(QWidget *parent) :
QDialog(parent),
ui(new Ui::RecruitSearch)
{
ui->setupUi(this);
}
RecruitSearch::~RecruitSearch()
{
delete ui;
}
void RecruitSearch::on_pushButton_clicked()
{
//if(EmployerSearch::ui->buttonBox->clicked();
if(ui->rfrId->text().isEmpty() || ui->rfrId->text().isNull() || (is_Digit(ui->rfrId->text().toStdString())==false) ){
QMessageBox::warning(this,"Error", "Please enter a valid RFR id(digits only)");
}
else{
accepted();
this->close();
}
}
int RecruitSearch:: getRfrId(){
return ui->rfrId->text().toInt();
}
bool RecruitSearch::is_Digit( string input){
for (int i = 0; i < input.length(); i++) {
if (!std::isdigit(input[i]))
return false;
}
return true;
}
Class with the display. How would I connect the two slots and use the id from the a first form to search a linkedlist then display results using another form:
#include "rfrform.h"
#include "ui_rfrform.h"
#include <cctype>
#include <string>
#include <QString>
#include <QtGui>
#include <QtCore>
#include <iostream>
using namespace std;
RfrForm::RfrForm(QWidget *parent) :
QDialog(parent),
ui(new Ui::RfrForm)
{
ui->setupUi(this);
}
RfrForm::~RfrForm()
{
delete ui;
}
void RfrForm::setEmpName(string name){
QString qstr=QString::fromStdString(name);
ui->EmployerName->setText(qstr);
}
void RfrForm::setAOE(string aoe){
QString qstr=QString::fromStdString(aoe);
ui->AOE->setText(qstr);
}
void RfrForm::setEmpId(int id){
QString qstr=QString::number(id);
ui->EmpId->setText(qstr);
}// end of setId
void RfrForm::setNumOfPos(int num){
QString qstr=QString::number(num);
ui->numOfPos->setText(qstr);
}
void RfrForm::setGender(string gen){
QString qstr=QString::fromStdString(gen);
ui->gender->setText(qstr);
}
void RfrForm::setMaxRecruits(int max){
QString qstr=QString::number(max);
ui->MaxRecruits->setText(qstr);
}
void RfrForm::display(RFR *temp){
this->show();
}
Think of signals and slots in Qt as simply callbacks. For instance, a standard signal/slot may look as follows:
....
QAction* act = new QAction(this);
connect(act, SIGNAL(triggered()), this, SLOT(handleAct()));
....
Note that the first parameter is a pointer to the object which will emit the signal (thus, the signal method, triggered in this case, must be associated with our sender, in this case QAction) and the second parameter is the signal function signature. Similarly, the last two arguments are the pointer for the slot (i.e. the event handler, in this case, the current class) and the function signature for some handler function.
This is for some class which looks like this (note the Q_OBJECT macro)
class TestMe
{
Q_OBJECT
public:
...
protected slots:
void handleAct();
};
Where the handleAct() method is some arbitrary function you design. Now, to answer your question more specifically, we will need more detail on exactly which type of QWidget you are using (i.e. so we know which signals it emits). In any case, the basic idea is to catch a particular type of symbol from a particular element, and then handle the information accordingly.
Sometimes, to do a type of information transfer you are looking for, you may need to hold particular pointers to objects as class members so you can easily get a the information in the corresponding QWidget (generally a text() method or similar).
It is also important to notice, however, that you can override QWidget types and created custom signals and slots. So if you have a custom signal which returns an id and a signal which takes an id value as input, you can connect these signals and slots (look into the emit functionality)
If you provide some more specific information about the QWidget you are using, we may be able to provide you a more specific solution.