I have a piece of code like this :
if(keyEvent->key()==Qt::Key_S && keyEvent->modifiers()==Qt::AltModifier)
{
// my code
}
I want to replace Qt::Key_S and Qt::AltModifier by two strings "KEY_S" and "ALT" which I intend to read from a file. I have no idea how to do it. I have tried QKeySequence, which is not working. Can anyone help?
If you get the Qt::Key value in a QKeyEvent then just use QKeyEvent::text() :
QString stringKey = event->text();
But as it is stated in the doc :
Return values when modifier keys such as Shift, Control, Alt, and Meta
are pressed differ among platforms and could return an empty string.
So you might want to handle them one by one, just by giving them the string you want to associate :
if (event->key() == Qt::Key_Alt)
QString stringKey = "ALT";
You can use Qt meta object system to get real names of enum keys as strings at runtime:
void keyPressEvent(QKeyEvent* e) {
int enum_index = qt_getQtMetaObject()->indexOfEnumerator("Key");
const char* string =
qt_getQtMetaObject()->enumerator(enum_index).valueToKey(e->key());
qDebug() << string;
}
Note that valueToKey may return null pointer if there is no corresponding key.
Related
New to Qt. Still learning it. I have clone.ui, clone.h and clone.cpp. clone ui has 2 buttons.
Browse button-> to Selection a destination path
Add button -> Clone(copy) a file
Clone.h
QString destination_path;
QFileDialog *fdialog;
Clone.cpp has
QFileInfo finfo; // Declare outside function to increase scope
QString destination_name;
void Clone:: on_pushButton__Browse_clicked()
{
/*get the destination path in QString using QFileDialog
Got destination_path */
QString destinatino_path = QFileDialog::getExistingDirectory(....);
QFile finfo(destination_path);
// QFileDialog finfo(destionation_path)
}`
In the same file Clone.cpp
void Clone:: on_btn_Add_clicked()
{
// how to get the same destination_path value here...
//using QFile or some other way?
}
I struck here, Am i missing anything? Any thoughts/suggestion highly useful.
You've create a class (Clone) which has a data member QString destination_path.
Since it is a member variable it has class scope (as in you can access the same variable in any Clone:: member function for the same Clone object).
The problem is that you've hidden it by declaring another QString destination_path in Clone::on_pushButton__Browse_clicked().
void Clone::on_pushButton__Browse_clicked()
{
...
// this *hides* the class member with the same name
QString destination_path = QFileDialog::getExistingDirectory(....);
...
}
The solution is to remove QString from the beginning of the line, which means you are now assigning to the class object's data member.
void Clone::on_pushButton__Browse_clicked()
{
...
// now you're assigning to your object's data member
destination_path = QFileDialog::getExistingDirectory(....);
...
}
Later, in Clone::on_btn_Add_clicked() you can access destination_path, and it will have the value assigned to it in Clone::on_pushButton__Browse_clicked
I want to create a numeric TextField which will be localized.
For example, in Excel, if you are in english, if you type a number with the KeyPad, the decimal separator key will enter a dot '.'
But if you are in French, the decimal separator will be a comma ','
Therefore in Excel, the TextField is smart enough to detect in which Locale you're on, and to adapt the decimal separator you actually wanted to print in the TextField.
Right now in JavaFX, I haven't found a way to do that. I was thinking of listening to text modification and to replace any occurrence of dot with a comma if I detect I'm in French. But is this assumption true?
I would recommend subclassing TextField and overriding the insertText and replace* methods. This will handle text entry before the text is updated; listening to text modifications and fixing them will mean you temporarily have "invalid" text in your text field's text property, which could create problems in the rest of your application.
Note that you can create a java.text.DecimalFormatSymbols object for the default (user) Locale (or a specified Locale, if you need), and call getDecimalSeparator() to find the correct decimal separator character. (Similarly, you can call getGroupingSeparator().)
So, for proof of concept, this is nowhere near robust enough for production:
public class NumericTextField extends TextField {
#Override
public void insertText(int index, String text) {
String fixedText = fixText(text);
StringBuilder newText = new StringBuilder(getText().substring(0, index));
newText.append(fixedText);
if (index < getText().length()) {
newText.append(getText().substring(index));
}
if (isValid(newText)) {
super.insertText(index, fixedText);
}
}
#Override
public void replaceText(int start, int end, String text) {
String fixedText = fixText(text);
StringBuilder newText = new StringBuilder(getText().substring(0, start));
newText.append(fixedText);
newText.append(getText().substring(end));
if (isValid(newText)) {
super.insertText(start, end, fixedText);
}
}
#Override
public void replaceText(IndexRange range, String text) {
replaceText(range.getStart(), range.getEnd(), text);
}
private String fixText(String text) {
DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();
return text.replaceAll("\\.", Character.toString(symbols.getDecimalSeparator()));
}
private boolean isValid(String text) {
// check that the text is a valid numeric representation (or partial representation)
}
}
In the events of a TextField, "setOnKeyPressed" and "setOnKeyReleased", the code of the key pressed can be obtained from the keyEvent and there it can be seen that the key code of the "." pressed from the main keyboard corresponds to the constant "PERIOD", while the keystroke code of "." pressed from the numeric keypad corresponds to the constant "DECIMAL".
From this concept, I share the closest thing I have achieved in this regard, where if I press the "." From the numeric keyboard, according to my specific need, I replace it with the character ",".
totalAmountText.setOnKeyReleased((keyEvent) -> {
if (keyEvent.getCode() == DECIMAL) {
int pos = totalAmountText.getCaretPosition();
totalAmountText.setText(totalAmountText.getText().replace(".", ","));
totalAmountText.positionCaret(pos);
}
});
I am attaching a new version of the code, which takes best practices from the code of the first answer:
totalAmountText.setOnKeyReleased((keyEvent) -> {
if (keyEvent.getCode() == DECIMAL) {
int pos = totalAmountText.getCaretPosition();
DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();
totalAmountText.setText(totalAmountText.getText().replace(".",
Character.toString(symbols.getDecimalSeparator())));
totalAmountText.positionCaret(pos);
}
});
Right now I cant even compile this program. Im trying to write a program that takes a inputted string and then encrypts the letters by swapping them out with another letter predetermined in a array and then shows you again the original text. any help would be appreciated.
import java.util.Scanner;
public class Array {
private char [] alphabet = new char [25];
private char [] crypt = new char [25];
String oldMessage;
public Array()
{ char[] alphabet = "abcdefghijklmnoptqrstuvwxyz".toCharArray();
char[] crypt = "qwertyuiopasdfghjklzxcvbnm|".toCharArray();
}
public static void run(){
Scanner scan = new Scanner(System.in);
System.out.println("Enter a message that you would like to encrypt\n");
oldMessage = scan.nextLine();
String newMessage = "";
for (int i=0; i<oldMessage.length(); ++i) {
int index = alphabet.indexOf(old.charAt(i));
if (index == -1)
newMessage +="?";
else
newMessage += crypt.charAt(index);
/**
* #param args the command line arguments
*/
public static void main(String[] args) {Array myApplication = new Array(); myApplication.run();}
First off, when encountering errors, it's always best to include the error in your question--often it will point you right to the source of the error. What does your compiler say when the build fails?
Next, I'm on my phone right now and can't verify that I've found all the problems, but remember that strings in Java are immutable, meaning that they can't be changed after creation. This means that you can't append to them in the way you're doing. Try using the StringBuilder class to accomplish what you're looking for here, or filling a new array as you go and converting to String at the end.
Also, it looks like you're missing two end braces (the for loop and the run method).
From static method run() you are referring to non-static variables like alphabet, crypt, oldMessage.
This is first that comes into mind
I want to save an alredy-existing QSettings object into some INI file for backup.
The QSettings comes from the application's global settings, ie. it can be registry, ini file, etc.
In case it helps, my context is:
class Params
{
// All params as data members
// ...
void loadGlobal ()
{
Qettings s; // Global parameters, paths set by application
// Fill data members: s.value (...);
}
};
class Algo
{
Result run (Params p)
{
Result r = F(p);
return r;
}
};
int main (...)
{
Params p;
p.loadGlobal ();
Algo a;
Result r = a.run (p);
// At this point, save Result and Params into a specific directory
// Is there a way to do:
p.saveToIni ("myparams.ini"); // <-- WRONG
}
A solution would be to add a saveTo (QSetting & s) method into the Params class:
class Params
{
void saveTo (QSettings & s)
{
s.setValue (...);
}
};
int main (...)
{
Params p;
p.loadGlobal ();
QSettings bak ("myparams.ini", ...);
p.saveTo (bak);
}
But I am looking for a solution without modifying the Params class.
Well, no, QT Doesn't really support this directly. I think your best bet is writing a helper class...something like:
void copySettings( QSettings &dst, QSettings &src )
{
QStringList keys = src.allKeys();
for( QStringList::iterator i = keys.begin(); i != keys.end(); i++ )
{
dst.setValue( *i, src.value( *i ) );
}
}
I think there are 2 issues:
QSettings does not have a copy constructor or assignment operator (that I know of), so you'll probably have to write your own copy using allKeys().
You can't save QSettings to an arbitrary file, but what you can do is set the path used for a specific format and scope using the static method QSettings::setPath(). Note that you need to do that before your backup QSettings object is created (and you would use format IniFormat).
If you're OK not having complete control over the resulting path, this should be sufficient. If not, you could still do the above, then get the file name using fileName() and use a system call to copy/move the file to the desired final location.
I have in an Object an QVector of Coordinates (my type) that I want to transfer to an other Vector ( I validate and than want to use ist ).
Header
bool getVector(QVector<Coordinates> &getCoordinates );
C File
static QVector<Coordinates> current;
int getVector( QVector<Coordinates> &getCoordinates)
{
.... stuff ...
getCoordinates = current;
.... stuff ....
return 0;
}
And I use it like
....
QVector<Coordinates> currentCoordinates;
getVector(currentCoordinates);
currentCoordinates.X // CRASH
The debugger goes to this line where an Live Crash happens
inline QVector(const QVector<T> &v) : d(v.d) { d->ref.ref(); if (!d->sharable) detach_helper(); }
So my how can I fix this? As I can use this to get all the other Variables with this methode.
A likely cause of your problem is that current has not been constructed before getVector is called. Initialization of static objects in C++ is a thorny area, and a frequent source of bugs - for more information, see this question, and the static initialization order fiasco FAQ entry.
A simple solution to this problem is to provide access to current via a function, i.e. replace
static QVector<Coordinates> current;
with
static QVector<Coordinates>& getCurrent()
{
static QVector<Coordinates> current;
return current;
}
Note, however, that the function as written above is not thread-safe. If multiple threads may call getCurrent, then it should be protected with a QMutex.
For gareth and the Forum :
the header:
typedef QVector<Coordinates> VesselCoordinates;
bool (*getVessel)(Charakter forCharakter, Vessel& getVessel,VesselCoordinates &getCoordinates );
later i bind tis function pointer to an static function ( cause this part of my Program will be one day convertet to c)
cpp file lower layer:
static struct {
Charakter currentPlayerVessel;
VesselCoordinates possibility;
}data;
static bool getVessel(Charakter forCharakter, Vessel& getVessel,VesselCoordinates &getCoordinates );
// funktion to bind the funktion pointer to this static funktion so it can be called outside the File
static bool serverNamespace::getVessel(Charakter forCharakter, Vessel& getVessel,VesselCoordinates &getCoordinates )
{
bool retValue= false;
if ( forCharakter == data.currentPlayerVessel){
// TODO abfragen ob die Adresse regestriert ist!
if ((true == minSize()) and ((true == shipsInRow())or (true == shipsInLine())))
{
retValue = true;
Vessel test = (Vessel)data.possibility.size();
getVessel = test;
getCoordinates = data.possibility;
}
}
return retValue;
}
And then i can use this in the upper layer cpp file to get the information i need:
// in an Funktion :
VesselCoordinates currentCoordinates;
currentCoordinates.clear();
Vessel currentVessel;
if (true == basicFleet->getVessel(currentCharakter,currentVessel, currentCoordinates ))
// doing stuff to it
so its worik fine but your idea worked just as fine. Maybe you can see why my idea is also working.
Thank you
elektor