英文:
Why is the comma in two text fields put at the same time without focusing?
问题
当按下逗号键时,如何在代码中更改条件?以使在键入时逗号不会同时出现在文本框1和2中,而是分开?在这些文本字段中的字符限制也发生了相同的情况。如何在两个文本字段之间分割处理?为什么逗号会在没有焦点的文本字段中放置?
import controlP5.*;
ControlP5 cp5;
Textfield X9;
Textfield X10;
void setup() {
size(700, 400);
PFont font = createFont("arial", 20);
cp5 = new ControlP5(this);
X9 = cp5.addTextfield("1")
.setPosition(20, 100)
.setSize(200, 40);
X9.setInputFilter(ControlP5.INTEGER)
.setFont(font)
.setAutoClear(false)
.setColor(color(255, 0, 0))
;
X10 = cp5.addTextfield("2")
.setPosition(20, 170)
.setSize(200, 40);
X10.setInputFilter(ControlP5.INTEGER)
.setFont(createFont("arial", 20))
.setAutoClear(false)
;
textFont(font);
}
void draw() {
background(0);
fill(255);
}
public void keyPressed(KeyEvent e) {
if (e.getKey() == ','){
X9.setText(X9.getText() + ',');
}
{
// if(X10.getText().length()>=4) { X10.setText(X10.getText().substring(0, 3));}
{
if (e.getKey() == ','){
X10.setText(X10.getText() + ',');
}
{
// if(X9.getText().length()>=4) { X9.setText(X9.getText().substring(0, 3));}
}
}
}
}
英文:
How can I change conditions in code when comma is pressed? So that the comma does not appear simultaneously in two text boxes 1 and 2 when typing, but separately? The same thing happens with the limitation of characters in these text fields. How to split the processing of two text fields among themselves! Why is the comma placed without focusing text fields?
Foto:
Complete code:
import controlP5.*;
ControlP5 cp5;
Textfield X9;
Textfield X10;
void setup() {
size(700,400);
PFont font = createFont("arial",20);
cp5 = new ControlP5(this);
X9 = cp5.addTextfield("1")
.setPosition(20,100)
.setSize(200,40);
X9.setInputFilter(ControlP5.INTEGER)
.setFont(font)
.setAutoClear(false)
.setColor(color(255,0,0))
;
X10 = cp5.addTextfield("2")
.setPosition(20,170)
.setSize(200,40);
X10.setInputFilter(ControlP5.INTEGER)
.setFont(createFont("arial",20))
.setAutoClear(false)
;
textFont(font);}
void draw() {
background(0);
fill(255);}
public void keyPressed(KeyEvent e) {
if (e.getKey() == ','){
X9.setText(X9.getText() + ',');}
{
// if(X10.getText().length()>=4) { X10.setText(X10.getText().substring(0, 3));}
{
if (e.getKey() == ','){
X10.setText(X10.getText() + ',');}
{
// if(X9.getText().length()>=4) { X9.setText(X9.getText().substring(0, 3));}
}}}
}
答案1
得分: 1
为什么逗号没有集中在文本字段上放置?
因为您正在使用全局的 keyPressed()
事件。这个条件:if (e.getKey() == '',')'
检查逗号键是否被按下,但在您的情况下检查两次是多余的。它等同于这个更简单/更干净的代码片段:
public void keyPressed(KeyEvent e) {
if (key == ','){
X9.setText(X9.getText() + ',');
X10.setText(X10.getText() + ',');
}
}
没有检查字段是否被聚焦。
您可能是想要这样的行为?:
public void keyPressed(KeyEvent e) {
if (key == ',') {
if (X9.isFocus()) {
X9.setText(X9.getText() + ',');
}
if (X10.isFocus()) {
X10.setText(X10.getText() + ',');
}
}
}
总体来说,主要目标不太清楚。也许有一种更简单的方法来实现它?
请记住,您可以通过 void controlEvent(ControlEvent event)
监听各个 ControlP5 组件的事件。查看 Processing > Examples > Contributed Libraries > ControlP5 > controllers > ControlP5Textfield 以获取漂亮的演示示例。
此外,我建议格式化/保持代码整洁。这可能只是一个快速的草图,但养成好习惯会有所回报,因为您将花费比编写代码更多的时间来阅读代码。随着程序变得越来越大,您会希望为未来的自己更轻松地工作。
更新 基于您的评论,以下是一个简单的草图,应该可以让您控制一个浮点数,范围在7.4到16.8之间,以及一个整数,范围在1800到1900之间:
import controlP5.*;
ControlP5 cp5;
int serialInt = 1800;
float serialFloat = 7.4;
void setup() {
size(300, 300);
noStroke();
cp5 = new ControlP5(this);
cp5.addNumberbox("serialInt")
.setBroadcast(false)
.setPosition(100, 100)
.setSize(100, 20)
.setMultiplier(10)
.setDirection(Controller.HORIZONTAL)
.setRange(1800, 9000)
.setBroadcast(true)
;
cp5.addNumberbox("serialFloat")
.setBroadcast(false)
.setPosition(100, 140)
.setSize(100, 20)
.setMultiplier(0.01)
.setDirection(Controller.HORIZONTAL)
.setRange(7.4, 16.8)
.setBroadcast(true)
;
}
void draw() {
background(0);
}
void controlEvent(ControlEvent event) {
println(event.getController().getName(), "changed value to", event.getValue(), "serialInt =", serialInt, "serialFloat =", serialFloat);
}
水平点击并拖动以更改值。
请注意 ControlP5 提供的一些有用功能:
- 如果您将控制器的名称与变量名相同,它们会自动连接:这大大节省了时间。(如果不能使用变量安全名称,可以查看 Examples > Contributed Examples > ControlP5 > use > ControlP5plugTo)
- 您可以轻松设置所需的范围和精度。
- 您可以选择使用
controlEvent()
来了解何时值发生了更改。
关于通过串口传输数据:
- 如果只需要0.1的精度,那么7.4到16.8的范围很容易:只需将值乘以10,将其调整为74到168,这适合在一个字节(0-255范围内)内。(您需要处理值,将其转换为整数再乘以10,以确保您在 ControlP5 中使用的是整数。)
- 1800到9000的范围要棘手一些,因为9000-1800 = 7200个步骤。为了这个精度,您至少需要13位(2 ^ 13 = 8192,可以容纳7200个值)。您可能需要在发送之前将其拆分为两个字节(2 ^ 16),使用 Processing 中的类似
highByte()
和lowByte()
的函数,然后在 Arduino 中(或者如果不使用 Arduino,则在等效的 STM32 Dev 工具中)使用word()
。
例如:
void serialWriteWord(Serial port, int value) {
port.write(highByte(value));
port.write(lowByte(value));
}
byte lowByte(int word) {
return (byte)(word & 0xff);
}
byte highByte(int word) {
return (byte)(word >> 8);
}
串口通信部分是一个完全不同的问题(需要另一个问题来详细讨论)。
英文:
> Why is the comma placed without focusing text fields?
Because you are using the global keyPressed()
event.
This condition: if (e.getKey() == ',')
checks that the ,
key is pressed and it's redundant to check twice in your case. It's equivalent to this simpler/cleaner snippet:
public void keyPressed(KeyEvent e) {
if (key == ','){
X9.setText(X9.getText() + ',');
X10.setText(X10.getText() + ',');
}
}
There isn't any check if a field is focused or not.
You probably meant something like this ?:
public void keyPressed(KeyEvent e) {
if (key == ',') {
if (X9.isFocus()) {
X9.setText(X9.getText() + ',');
}
if (X10.isFocus()) {
X10.setText(X10.getText() + ',');
}
}
}
Overall it's unclear what the main goal is. Perhaps there's a simpler way to achieve it ?
Remeber that you can listen for individual controlP5 component events via void controlEvent(ControlEvent event)
. See Processing > Examples > Contributed Libraries > ControlP5 > controllers > ControlP5Textfield for a nice demo.
Additionally I recommend formatting/keeping code tidy. It may be a quick throw-away sketch, but buiilding a good habbit will pay off as you'll spend way more time reading code than writing code. As your programs become larger and larger you'll want to make life easier for your future self
Update Based on your comments here is a minimal sketch that should allow you control a floating point number between 7.4 and 16.8 and an integer number between 1800-1900:
import controlP5.*;
ControlP5 cp5;
int serialInt = 1800;
float serialFloat = 7.4;
void setup() {
size(300,300);
noStroke();
cp5 = new ControlP5(this);
cp5.addNumberbox("serialInt") // notice the component name matches the variable name: controlP5 links the two for you
.setBroadcast(false) // disable events while we update value specific properties
.setPosition(100,100) // screen location
.setSize(100,20) // screen dimensions
.setMultiplier(10) // set the sensitifity of the numberbox: each step is 10
.setDirection(Controller.HORIZONTAL) // change the control direction to left/right
.setRange(1800, 9000) // set minimum, maximum value
.setBroadcast(true) // enable events (after setting range)
;
cp5.addNumberbox("serialFloat")
.setBroadcast(false) // disable events while we update value specific properties
.setPosition(100,140) // screen location
.setSize(100,20) // screen dimensions
.setMultiplier(0.01) // set the sensitifity of the numberbox: each step is 0.01
.setDirection(Controller.HORIZONTAL) // change the control direction to left/right
.setRange(7.4,16.8) // set minimum, maximum value
.setBroadcast(true) // enable events (after setting range)
;
}
void draw() {
background(0);
}
// gets called whenever a component updates value
void controlEvent(ControlEvent event){
println(event.getController().getName(),"changed value to",event.getValue(),"serialInt = ",serialInt,"serialFloat = ",serialFloat);
}
Click and drag horizontally to change values.
Notice a few helpful things that ControlP5 provides:
- if you name your controller the same name as the controller the two are connected automatically: huge time saver. (If you can't use variable safe name you can look at Examples > Contributed Examples > ControlP5 > use > ControlP5plugTo)
- you can easily set the range and precision desired
- you can use
controlEvent()
optionally to tell when a value changed
Regarding data over serial:
- 7.4 to 16.8 range is easy if you only need .1 precision: simply multiply the value by 10 bringing it to 74 to 168 which fits within a single byte (0-255 range)
- 1800 to 9000 range is trickier because 9000-1800 = 7200 steps in between. For this precision you would need at least 13 bits (2 ^ 13 = 8192 so can fit 7200 values). You might need to split that into two bytes (2 ^ 16) using something equivalent to
highByte()
andlowByte()
in Processing before sending andword()
in Arduino (or equivalent STM32 Dev tools if not using Arduino).
For example:
void serialWriteWord(Serial port,int value){
port.write(highByte(value));
port.write(lowByte(value));
}
byte lowByte(int word){
return (byte)(word & 0xff);
}
byte highByte(int word){
return (byte)(word >> 8);
}
The serial communication part is a totally separate issue (for another question)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论