

解答
SaveName変数のデフォルト値「RankingData」が入ってるか?
SaveNameのデフォルト値が Get SaveNameで使われてるか?

リファレンスの検索で最後に出てくる
WBP_Rankingで Cast して自分のゲームモードを読んでるか?

できた



SaveName変数のデフォルト値「RankingData」が入ってるか?
SaveNameのデフォルト値が Get SaveNameで使われてるか?

リファレンスの検索で最後に出てくる
WBP_Rankingで Cast して自分のゲームモードを読んでるか?

できた

スラスラC++で、実行するとエラー
C:\samples\chapter04\4_5>cd C:\samples\chapter04\4_5\
C:\samples\chapter04\4_5>g++ -o list4_5.exe list4_5.cpp
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe:
C:\Users\furcr\AppData\Local\Temp\ccs3yFYU.o:list4_5.cpp:(.text+0x72):
undefined reference to `getBmi(double, double)' collect2.exe: error:
ld returned 1 exit statuschapter4.h
// BMIを求める関数のプロトタイプ宣言
double getBmi(double height, double weight);getBmi.cpp
double getBmi(double height, double weight) {
double bmi; // BMIの計算結果を入れる
// cm単位をm単位にする
height /= 100;
// BMIを計算する
bmi = weight / height / height;
// 戻り値としてBMIを返す
return bmi;
}
list4_5.cpp
#include <iostream>
using namespace std;
#include "chapter4.h"
int main() {
double height; // 身長
double weight; // 体重
double bmi; // BMI
// キー入力をheightに格納する
cout << "身長(cm)を入力してください:";
cin >> height;
// キー入力をweightに格納する
cout << "体重(kg)を入力してください:";
cin >> weight;
// 身長と体重からBMIを計算する
bmi = getBmi(height, weight);
// BMIを画面に表示する
cout << "あなたのBMIは、" << bmi << "です。" << endl;
return 0;
}
cd_samples4_5_header.cmd
C:\samples\chapter04\4_5>cd C:\samples\chapter04\4_5\
C:\samples\chapter04\4_5>g++ list4_5.cpp getBmi.cpp -o list4_5.exe
C:\samples\chapter04\4_5>list4_5.exe
身長(cm)を入力してください:167
体重(kg)を入力してください:75
あなたのBMIは、26.8923です。
C:\samples\chapter04\4_5>cmd /k
C:\samples\chapter04\4_5>
chapter4.h ファイル内で getBmi(double height, double weight) 関数の実装が正しく行われていることを確認してください。chapter4.h には関数のプロトタイプ宣言が含まれているはずですが、実際の関数の定義が別のファイル(おそらく chapter4.cpp など)にあるはずです。list4_5.cpp と関連するファイルを一緒に指定する必要があります。例えば、次のようにコンパイルしてみてください。g++ list4_5.cpp getBmi.cpp -o list4_5.exe
chapter4.cpp のファイル名は実際のファイル名に合わせて修正してください。maya python How can I enter a regular expression for search from the created text field?
import maya.cmds as cmds
import re
def search_objects_by_regex(*args):
# テキストフィールドから正規表現を取得
regex_pattern = cmds.textField("regexField", query=True, text=True)
# シーン内のすべてのオブジェクトを取得
all_objects = cmds.ls()
# 正規表現パターンをコンパイル
try:
regex = re.compile(regex_pattern)
except re.error as e:
cmds.warning(f"Invalid regex pattern: {e}")
return
# 正規表現に一致するオブジェクトをフィルタリング
matching_objects = [obj for obj in all_objects if regex.search(obj)]
# 結果を表示
if matching_objects:
cmds.confirmDialog(title='Search Results', message='\n'.join(matching_objects))
else:
cmds.confirmDialog(title='Search Results', message='No matching objects found.')
# UIの作成
if cmds.window("regexSearchWindow", exists=True):
cmds.deleteUI("regexSearchWindow")
cmds.window("regexSearchWindow", title="Regex Search", widthHeight=(300, 100))
cmds.columnLayout(adjustableColumn=True)
cmds.text(label="Enter Regex Pattern:")
cmds.textField("regexField")
cmds.button(label="Search", command=search_objects_by_regex)
cmds.showWindow("regexSearchWindow")検索置換の場合
import maya.cmds as cmds
import re
def replace_objects_by_regex(*args):
# テキストフィールドから正規表現と置換文字列を取得
regex_pattern = cmds.textField("regexField", query=True, text=True)
replace_text = cmds.textField("replaceField", query=True, text=True)
# シーン内のすべてのオブジェクトを取得
all_objects = cmds.ls()
# 正規表現パターンをコンパイル
try:
regex = re.compile(regex_pattern)
except re.error as e:
cmds.warning(f"Invalid regex pattern: {e}")
return
# 正規表現に一致するオブジェクトを置換
replaced_objects = [regex.sub(replace_text, obj) for obj in all_objects]
# 結果を表示
if replaced_objects:
cmds.confirmDialog(title='Replace Results', message='\n'.join(replaced_objects))
else:
cmds.confirmDialog(title='Replace Results', message='No objects replaced.')
# UIの作成
if cmds.window("regexReplaceWindow", exists=True):
cmds.deleteUI("regexReplaceWindow")
cmds.window("regexReplaceWindow", title="Regex Replace", widthHeight=(300, 150))
cmds.columnLayout(adjustableColumn=True)
cmds.text(label="Enter Regex Pattern:")
cmds.textField("regexField")
cmds.text(label="Enter Replace Text:")
cmds.textField("replaceField")
cmds.button(label="Replace", command=replace_objects_by_regex)
cmds.showWindow("regexReplaceWindow")
rename_asset(asset, newName) 色々あるが基本はこれでいい。むしろこれしか動かず。
editor_util = unreal.EditorUtilityLibrary()
# 新しい名前
newName = newName
# リネームしたいアセット
asset = unreal.load_asset(package_name)
# rename実行
editor_util.rename_asset(asset, newName)複数ファイルに対応する。
def rename_endZ_remove_loop(self):
editorAssetLib = unreal.EditorAssetLibrary()
editor_util = unreal.EditorUtilityLibrary()
#editorStaticMeshLib = unreal.EditorStaticMeshLibrary()
MaterialEditingLibrary = unreal.MaterialEditingLibrary()
asset_registry = unreal.AssetRegistryHelpers.get_asset_registry()
#import unreal.AssetRegistry
#AssetRegistry=unreal.AssetRegistry()
EnvName=unreal.Name.cast("/Game/Effects")
#EnvName=unreal.Name.cast(readDirPath)
EnvArr=unreal.AssetRegistry.get_assets_by_path(asset_registry,EnvName,True,False)
#EnvArr = asset_registry.get_assets()
#EnvArr =self.SelectedAssets
unreal.log_warning("main_way_start2 040 unreal.AssetRegistry.get_assets_by_path(asset_registry,EnvName,True,False)")
unreal.log_warning("main_way_start2 041 get_assets_by_path() EnvArr len= "+str(len(EnvArr)))
NGlist=[]
checkout_Arr=[]
checkout_Arr_Str=""
rename_data_Arr=[]
total_frames = len(EnvArr)
text_label = "Rename Execution!"
with unreal.ScopedSlowTask(total_frames, text_label) as slow_task:
slow_task.make_dialog(True) # まだダイアログが表示されていない場合は表示します
for i in range(total_frames):
if slow_task.should_cancel():# ユーザーが UI の [Cancel] を押した場合は True
break
slow_task.enter_progress_frame(1)# 1 フレーム次に進めます。
AssetData=EnvArr[i]
print("AssetData= "+str(AssetData))
package_name=str(AssetData.package_name)
print("package_name= "+str(package_name))
package_name_Arr=package_name.split("/")
package_name_Arr_len=len(package_name_Arr)
print("package_name_Arr_len= "+str(package_name_Arr_len))
assetName=package_name_Arr[package_name_Arr_len-1]
print("assetName= "+str(assetName))
assetNameStr=str(assetName)+"."
# 新しい名前
newName=assetNameStr.replace("Z.","")
# リネームしたいアセット
asset = unreal.load_asset(package_name)
# 新しいパッケージパス
new_package_path = package_name+"."
new_package_path=new_package_path.replace("Z.","")
editor_util.rename_asset(asset, newName)
# リネームデータを作成
#rename_data = unreal.AssetRenameData(asset, new_package_path, new_name)
#unreal.EditorUtilityLibrary.rename_asset(rename_data)
#rename_data_Arr.append(rename_data)
#rename_assets(rename_data_Arr)依存関係のあるファイルをチェックアウトしてからリネーム
# -*- coding: utf-8 -*-
import unreal
import sys
import os
import re
import codecs
import os
import datetime
unreal.log("--------------py--start000-----------------")
unreal.log(" ")
class RefferenceCounter():
def mainWay(self):
self.AssetRegistryLoaded=False
#----------------------------------------------------------
self.tickhandle = None
self.tickhandle = unreal.register_slate_pre_tick_callback(self.testRegistry)
print("tickhandle="+str(self.tickhandle))
def testRegistry(self,deltaTime):
unreal.log_warning("ticking...mainWay")
asset_registry = unreal.AssetRegistryHelpers.get_asset_registry()
if asset_registry.is_loading_assets():
unreal.log_warning("still loading...mainWay")
else:
unreal.log_warning("ready!.....mainWay")
if(self.AssetRegistryLoaded==False):
self.AssetRegistryLoaded=True
self.textLoad2()
#self.textLoad()
unreal.unregister_slate_pre_tick_callback(self.tickhandle)
unreal.unregister_slate_pre_tick_callback(self.tickhandle)
def getProject_SavedDir(self):
project_saved_dir=unreal.Paths.project_saved_dir()
print("project_saved_dir= "+project_saved_dir)
HD_project_saved_dir=os.path.abspath(project_saved_dir)
print("HD_project_saved_dir= "+HD_project_saved_dir)
HD_project_saved_dir_slash=HD_project_saved_dir.replace('\\', '/')
print("HD_project_saved_dir_slash= "+HD_project_saved_dir_slash)
return HD_project_saved_dir_slash
def get_project_dir(self):
project_dir=unreal.Paths.project_dir()
print("project_dir= "+project_dir)
HD_project_dir=os.path.abspath(project_dir)
print("HD_project_dir= "+HD_project_dir)
HD_project_dir_slash=HD_project_dir.replace('\\', '/')
print("HD_project_dir_slash= "+HD_project_dir_slash)
return HD_project_dir_slash
def textLoad2(self):
import codecs
readPath=self.getProject_SavedDir()+'/RefferenceCounter/SelectedAsset.txt'
print("readPath= "+readPath)
fin = codecs.open(readPath, 'r', 'utf_8')
SelectedAssetArr=[]
for line in fin:
line=line.replace(" ","")#Space
line=line.replace(" ","")#TAB
line=line.replace("\r","")
line=line.replace("\n","")
if(line==""):
pass
else:
SelectedAssetArr.append(line)
#txtData=fin.read()
print("SelectedAssetArr= "+str(SelectedAssetArr))
#rejectLines=txtData
#print("SelectedAssets= "+SelectedAssets)
self.SelectedAssets=SelectedAssetArr
self.main_way_start2()
def main_way_start2(self):
editorAssetLib = unreal.EditorAssetLibrary()
editor_util = unreal.EditorUtilityLibrary()
#editorStaticMeshLib = unreal.EditorStaticMeshLibrary()
MaterialEditingLibrary = unreal.MaterialEditingLibrary()
asset_registry = unreal.AssetRegistryHelpers.get_asset_registry()
#import unreal.AssetRegistry
#AssetRegistry=unreal.AssetRegistry()
EnvName=unreal.Name.cast("/Game/Materials")
EnvName_Str=editor_util.get_current_content_browser_path()
EnvName=unreal.Name.cast(EnvName_Str)
#EnvName=unreal.Name.cast(readDirPath)
EnvArr=unreal.AssetRegistry.get_assets_by_path(asset_registry,EnvName,True,False)
unreal.log_warning("main_way_start2 040 unreal.AssetRegistry.get_assets_by_path(asset_registry,EnvName,True,False)")
unreal.log_warning("main_way_start2 041 get_assets_by_path() EnvArr len= "+str(len(EnvArr)))
NGlist=[]
checkout_Arr=[]
checkout_Arr_Str=""
total_frames = len(EnvArr)
text_label = "reference And Dependency Checking!"
with unreal.ScopedSlowTask(total_frames, text_label) as slow_task:
slow_task.make_dialog(True) # まだダイアログが表示されていない場合は表示します
for i in range(total_frames):
if slow_task.should_cancel():# ユーザーが UI の [Cancel] を押した場合は True
break
slow_task.enter_progress_frame(1)# 1 フレーム次に進めます。
#package_name=EnvArr[i]
AssetData=EnvArr[i]
print("AssetData= "+str(AssetData))
package_name=str(AssetData.package_name)
print("package_name= "+str(package_name))
package_name_Arr=package_name.split("/")
package_name_Arr_len=len(package_name_Arr)
print("package_name_Arr_len= "+str(package_name_Arr_len))
assetName=package_name_Arr[package_name_Arr_len-1]
print("assetName= "+str(assetName))
dependency_options=unreal.AssetRegistryDependencyOptions(include_soft_package_references=True, include_hard_package_references=True, include_searchable_names=False, include_soft_management_references=False, include_hard_management_references=False)
#
asset_registry = unreal.AssetRegistryHelpers.get_asset_registry()
dependencies=unreal.AssetRegistry.get_dependencies(asset_registry,package_name, dependency_options)
referencers=unreal.AssetRegistry.get_referencers(asset_registry,package_name, dependency_options)
dependencies_len=len(dependencies)
referencers_len=len(referencers)
print("----------------referencers_len= "+str(referencers_len)+"-------------------")
dependencies_str=self.array_to_str(dependencies)
referencers_str=self.array_to_str(referencers)
all_ref_dependencys_str=dependencies_str+"|"+referencers_str
all_ref_dependencys_len=referencers_len+dependencies_len
#A=assetName+","+assetPath
A=assetName+","+str(referencers_len)+","+referencers_str+","+str(dependencies_len)+","+dependencies_str+","
A=A+str(all_ref_dependencys_len)+","+all_ref_dependencys_str
checkout_Arr_Str=checkout_Arr_Str+all_ref_dependencys_str+"|"+package_name+"|"
#A=A+","+str(package_name)
#for dep in dependencies:
# A=A+","+str(dep)
NGlist.append(A)
unreal.log_warning(A)
# チェックアウト
checkout_Arr=checkout_Arr_Str.split("|")
for checkout_file_path in checkout_Arr:
if checkout_file_path=="":
pass
else:
unreal.EditorAssetLibrary.checkout_asset(checkout_file_path)
self.rename_endZ_remove_loop(EnvName_Str)
def rename_endZ_remove_loop(self,EnvName_Str):
editorAssetLib = unreal.EditorAssetLibrary()
editor_util = unreal.EditorUtilityLibrary()
#editorStaticMeshLib = unreal.EditorStaticMeshLibrary()
MaterialEditingLibrary = unreal.MaterialEditingLibrary()
asset_registry = unreal.AssetRegistryHelpers.get_asset_registry()
#import unreal.AssetRegistry
#AssetRegistry=unreal.AssetRegistry()
EnvName=unreal.Name.cast(EnvName_Str)
#EnvName=unreal.Name.cast(readDirPath)
EnvArr=unreal.AssetRegistry.get_assets_by_path(asset_registry,EnvName,True,False)
#EnvArr = asset_registry.get_assets()
#EnvArr =self.SelectedAssets
unreal.log_warning("main_way_start2 040 unreal.AssetRegistry.get_assets_by_path(asset_registry,EnvName,True,False)")
unreal.log_warning("main_way_start2 041 get_assets_by_path() EnvArr len= "+str(len(EnvArr)))
NGlist=[]
checkout_Arr=[]
checkout_Arr_Str=""
rename_data_Arr=[]
total_frames = len(EnvArr)
text_label = "Rename Execution!"
with unreal.ScopedSlowTask(total_frames, text_label) as slow_task:
slow_task.make_dialog(True) # まだダイアログが表示されていない場合は表示します
for i in range(total_frames):
if slow_task.should_cancel():# ユーザーが UI の [Cancel] を押した場合は True
break
slow_task.enter_progress_frame(1)# 1 フレーム次に進めます。
AssetData=EnvArr[i]
print("AssetData= "+str(AssetData))
package_name=str(AssetData.package_name)
print("package_name= "+str(package_name))
package_name_Arr=package_name.split("/")
package_name_Arr_len=len(package_name_Arr)
print("package_name_Arr_len= "+str(package_name_Arr_len))
assetName=package_name_Arr[package_name_Arr_len-1]
print("assetName= "+str(assetName))
assetNameStr=str(assetName)+"."
# 新しい名前
newName=assetNameStr.replace("Z.","")
# リネームしたいアセット
asset = unreal.load_asset(package_name)
# 新しいパッケージパス
new_package_path = package_name+"."
new_package_path=new_package_path.replace("Z.","")
editor_util.rename_asset(asset, newName)
# リネームデータを作成
#rename_data = unreal.AssetRenameData(asset, new_package_path, new_name)
#unreal.EditorUtilityLibrary.rename_asset(rename_data)
#rename_data_Arr.append(rename_data)
#rename_assets(rename_data_Arr)
Class_Ins=RefferenceCounter()
Class_Ins.mainWay()CGWORLD.JPさんから引用、「リネームとリダイレクタはある意味密接な関係にある…
KAEditorUtilityBlueprintLibrary.h
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "KAEditorUtilityBlueprintLibrary.generated.h"
UCLASS()
class KAEDITORUTILITYTEST_API UKAEditorUtilityBlueprintLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
//RedirectorをFixUpする
UFUNCTION(BlueprintCallable, Category = "KAEditorUtility")
static void FixupRedirectors(const TArray<FAssetData>& Assets, bool bCheckoutDialogPrompt);
};KAEditorUtilityBlueprintLibrary.cpp
#include "KAEditorUtilityBlueprintLibrary.h"
#include "AssetToolsModule.h"
void UKAEditorUtilityBlueprintLibrary::FixupRedirectors(const TArray<FAssetData>& Assets, bool bCheckoutDialogPrompt)
{
FAssetToolsModule& AssetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>(TEXT("AssetTools"));
//Redirectorの取得
TArray<UObjectRedirector*> Redirectors;
for (FAssetData Object : Assets)
{
if (UObjectRedirector* Redirector = Cast<UObjectRedirector>(Object.GetAsset()))
{
Redirectors.Emplace(Redirector);
}
}
if (Redirectors.Num() > 0)
{
AssetToolsModule.Get().FixupReferencers(Redirectors, bCheckoutDialogPrompt);
return true;
}
return false;
}参考URL
https://cgworld.jp/regular/202312-ue5tool-01.html
https://docs.unrealengine.com/5.0/en-US/PythonAPI/class/EditorAssetLibrary.html
確認用のシステム、エミッター、モジュール、そしてNiagaraParameterCollectionのアセットを作ります。



名前は何でもいいので NiagaraParameterCollection 開いて、新しいパラメータfloatを一つ作ります。

最初のNiagaraParameterCollection設定は、これだけでOKです。
モジュール側の設定はこれで終了です。

次はエミッター側の設定です
ParticleSpawnに、先ほど作ったモジュールを追加します(自分でつけた名前で検索してください)

追加したモジュールに、MyFloat(設定した名前です)という部分に、数値が入るようになっていれば大丈夫です。
ここに入れた数字が、Lifetime(パーティクルの寿命)に設定されます。
設定しておくと、解りやすいと思います。

次に、NiagaraParameterCollectionを実際に入れていきます
まず、Parameterというウインドウを出します

ここから、追加したNiagaraParameterCollectionを登録します。

追加したら、この情報を、ドラッグして差し替えます。

このように登録されていればOKです。

ここまですれば、設定したNiagaraParameterCollectionファイルの数値を動かすと、このエミッターの寿命が延びたり縮んだりしていると思います。
実際に組み込んだ様子がこちら。
調整として使いやすいポイントとして、エミッター毎固定ではなく、システム毎に適用するデータを差し替える事が出来る点です。
エミッター自体の情報を差し替える必要がなく、システム側で変えることができるので、別のシステムで使うようのエミッターを流用していく事も可能です。
エミッター自体にNiagaraParameterCollectionデータを入れている場合でも、システム側でほかのデータに差し替える等も可能です。
HoudiniのHDAのような、いくつかのパラメータを変えるだけで簡単に調整出来る仕様というのも、段々出来ていくのかなと思います。
ということでした
参考URL
Partial copy of skin weights
MAYAでのウェイト作業でしたら、部分コピーできます。
1,コピー元とコピー先のオブジェクトを選択
2,F9で頂点選択モード
3,コピー元ウェイト範囲を頂点選択
4,コピー先のウェイト範囲を頂点選択
5,スキンウェイトのコピー
の手順でスキンウェイトの部分コピーできます。
んーできない。
できないとおもっていたら。
んーできない。結局ベースはコピーしてそこからスキンウェイトペイントした。
# -*- coding: utf-8 -*-
import os
from functools import partial
import time
import imp
"""
PySide2モジュールを探し、ある場合はそちらをインポートします。
"""
try:
imp.find_module('PySide2')
from PySide2.QtWidgets import *
from PySide2.QtGui import *
from PySide2.QtCore import *
except ImportError:
from PySide.QtGui import *
from PySide.QtCore import *
LOGO_IMAGE = r"画像のパスをここに入れてください。"
def get_maya_pointer():
"""
Mayaのメインウィンドウを取得する関数
"""
try:
import maya.cmds as cmds
from maya import OpenMayaUI
except ImportError:
return None
"""
実は2017ではshibokenも2になっているので、あればshiboken2をインポートします。
"""
try:
imp.find_module("shiboken2")
import shiboken2
return shiboken2.wrapInstance(int(OpenMayaUI.MQtUtil.mainWindow()), QWidget)
except ImportError:
import shiboken
return shiboken.wrapInstance(int(OpenMayaUI.MQtUtil.mainWindow()), QWidget)
class MyDialog(QDialog):
def __init__(self, parent = None, f = 0):
super(MyDialog, self).__init__(parent, f)
#-----------------------------------------------------------------------
# Layout
#-----------------------------------------------------------------------
mainLayout = QVBoxLayout()
self.setLayout(mainLayout)
#-----------------------------------------------------------------------
# Image
#-----------------------------------------------------------------------
imageWidget = QLabel()
imageWidget.setPixmap(QPixmap(LOGO_IMAGE))
mainLayout.addWidget(imageWidget)
#-----------------------------------------------------------------------
# Description
#-----------------------------------------------------------------------
description = QLabel("This is coustom dialog.")
mainLayout.addWidget(description)
#-----------------------------------------------------------------------
# Text input
#-----------------------------------------------------------------------
self._inputWidget = QLineEdit()
mainLayout.addWidget(self._inputWidget)
#-----------------------------------------------------------------------
# Buttons
#-----------------------------------------------------------------------
buttonArea = QHBoxLayout()
mainLayout.addLayout(buttonArea)
buttonArea.addStretch()
okBtn = QPushButton("OK")
buttonArea.addWidget(okBtn)
okBtn.clicked.connect(self.accept)
cancelBtn = QPushButton("Cancel")
buttonArea.addWidget(cancelBtn)
cancelBtn.clicked.connect(self.reject)
def getInputText(self):
return self._inputWidget.text()
class DF_TalkUI(QMainWindow):
def __init__(self, parent = None):
super(DF_TalkUI, self).__init__(parent)
self.setObjectName("DF_Talk_Window")
self.setWindowTitle("DF Talk Window")
#self._initUI()
self.errorDialog = QErrorMessage(self) # QErrorMessageインスタンスの保持
def myInit(self,qApp):
self.qApp=qApp
wrapper = QWidget()
self.setCentralWidget(wrapper)
mainLayout = QVBoxLayout()
wrapper.setLayout(mainLayout)
#-----------------------------------------------------------------------
# First row
#-----------------------------------------------------------------------
firstHolizontalArea = QHBoxLayout()
firstHolizontalArea.setSpacing(20)
mainLayout.addLayout(firstHolizontalArea)
labelArea = QVBoxLayout()
firstHolizontalArea.addLayout(labelArea)
labelWidget = QLabel("Text is shown like this.")
labelArea.addWidget(labelWidget)
imageWidget = QLabel()
imageWidget.setPixmap(QPixmap(LOGO_IMAGE))
labelArea.addWidget(imageWidget)
labelArea.addStretch()
textArea = QTextEdit()
textArea.setPlainText("Text are\ncan be set\nmultiple lines and HTML.")
firstHolizontalArea.addWidget(textArea)
mainLayout.addWidget(self._makeHorizontalLine())
#-----------------------------------------------------------------------
# Second row
#-----------------------------------------------------------------------
secondHolizontalArea = QHBoxLayout()
secondHolizontalArea.setSpacing(20)
mainLayout.addLayout(secondHolizontalArea)
lineEdit = QLineEdit()
lineEdit.setMaximumWidth(200)
lineEdit.setText("This widget is useful for inputting text")
secondHolizontalArea.addWidget(lineEdit)
comboBox = QComboBox()
comboBox.addItems(["This", "is", "combobox", "it's", "useful"])
comboBox.setEditable(True)
comboBox.setInsertPolicy(QComboBox.NoInsert)
comboBox.completer().setCompletionMode(QCompleter.PopupCompletion)
secondHolizontalArea.addWidget(comboBox)
spinBox = QSpinBox()
spinBox.setMinimum(0)
spinBox.setMaximum(10)
spinBox.setSuffix("min")
secondHolizontalArea.addWidget(spinBox)
mainLayout.addWidget(self._makeHorizontalLine())
#-----------------------------------------------------------------------
# Third row
#-----------------------------------------------------------------------
thirdHorizontalArea = QHBoxLayout()
thirdHorizontalArea.setSpacing(20)
mainLayout.addLayout(thirdHorizontalArea)
checkBox = QCheckBox("Check box")
thirdHorizontalArea.addWidget(checkBox)
checkBox.setChecked(True)
radioArea = QVBoxLayout()
thirdHorizontalArea.addLayout(radioArea)
radioGroup = QButtonGroup(self)
radioBtn1 = QRadioButton("Option 1")
radioArea.addWidget(radioBtn1)
radioGroup.addButton(radioBtn1)
radioBtn2 = QRadioButton("Option 2")
radioArea.addWidget(radioBtn2)
radioGroup.addButton(radioBtn2)
radioBtn3 = QRadioButton("Option 3")
radioArea.addWidget(radioBtn3)
radioGroup.addButton(radioBtn3)
radioBtn1.setChecked(True)
mainLayout.addWidget(self._makeHorizontalLine())
#-----------------------------------------------------------------------
# Fourth row
#-----------------------------------------------------------------------
fourthHorizontalArea = QHBoxLayout()
fourthHorizontalArea.setSpacing(20)
mainLayout.addLayout(fourthHorizontalArea)
calender = QCalendarWidget()
fourthHorizontalArea.addWidget(calender)
calender.setMaximumWidth(300)
lcdNumber = QLCDNumber()
fourthHorizontalArea.addWidget(lcdNumber)
lcdNumber.display(1234)
sliderArea = QVBoxLayout()
fourthHorizontalArea.addLayout(sliderArea)
sliderDisplay = QLabel("0")
sliderArea.addWidget(sliderDisplay)
slider = QSlider(Qt.Horizontal)
sliderArea.addWidget(slider)
slider.setRange(0, 100)
slider.setTickPosition(QSlider.TicksBothSides)
slider.setSingleStep(5)
slider.setPageStep(10)
slider.setTickInterval(10)
slider.valueChanged.connect(lambda val: sliderDisplay.setText(str(val)))
slider.setValue(0)
dialDisplay = QLabel("0")
sliderArea.addWidget(dialDisplay)
dial = QDial()
sliderArea.addWidget(dial)
dial.setRange(0, 100)
dial.setSingleStep(5)
dial.setPageStep(10)
dial.setNotchesVisible(True)
dial.setWrapping(True)
dial.setNotchTarget(5)
dial.valueChanged.connect(lambda val: dialDisplay.setText(str(val)))
dial.setValue(0)
mainLayout.addWidget(self._makeHorizontalLine())
#-----------------------------------------------------------------------
# fifth row
#-----------------------------------------------------------------------
fifthHorizontalArea = QHBoxLayout()
fifthHorizontalArea.setSpacing(20)
mainLayout.addLayout(fifthHorizontalArea)
fifthHorizontalArea.addWidget(self._makeListWidget())
fifthHorizontalArea.addWidget(self._makeTableWidget())
fifthHorizontalArea.addWidget(self._makeTreeWidget())
mainLayout.addWidget(self._makeHorizontalLine())
#-----------------------------------------------------------------------
# sixth row
#-----------------------------------------------------------------------
sixthHorizontalArea = QHBoxLayout()
sixthHorizontalArea.setSpacing(20)
mainLayout.addLayout(sixthHorizontalArea)
msgBoxBtn = QPushButton("Message Dialog")
sixthHorizontalArea.addWidget(msgBoxBtn)
msgBoxBtn.clicked.connect(partial(QMessageBox().information, self, "Message", "This is normal information message."))
colorDialogBtn = QPushButton("Color Dialog")
sixthHorizontalArea.addWidget(colorDialogBtn)
colorDialogBtn.clicked.connect(self._showColorDialog)
progressDialogBtn = QPushButton("Progress Dialog")
sixthHorizontalArea.addWidget(progressDialogBtn)
progressDialogBtn.clicked.connect(self._showProgressDialog)
fileDialogBtn = QPushButton("File Dialog")
sixthHorizontalArea.addWidget(fileDialogBtn)
fileDialogBtn.clicked.connect(partial(QFileDialog.getOpenFileName, self, "File Select", options = QFileDialog.DontUseNativeDialog))
#-----------------------------------------------------------------------
# seventh row
#-----------------------------------------------------------------------
seventhHorizontalArea = QHBoxLayout()
seventhHorizontalArea.setSpacing(20)
mainLayout.addLayout(seventhHorizontalArea)
errorMsgBtn = QPushButton("Error Dialog")
seventhHorizontalArea.addWidget(errorMsgBtn)
errorMsgBtn.clicked.connect(self._showErrorDialog)
inputDialogTextBtn = QPushButton("Input (text)")
seventhHorizontalArea.addWidget(inputDialogTextBtn)
inputDialogTextBtn.clicked.connect(self._showInputTextDialog)
inputDialogComboBtn = QPushButton("Input (combo)")
seventhHorizontalArea.addWidget(inputDialogComboBtn)
inputDialogComboBtn.clicked.connect(self._showInputComboDialog)
dialogBtn = QPushButton("Custom Dialog")
seventhHorizontalArea.addWidget(dialogBtn)
dialogBtn.clicked.connect(self._showCustomDialog)
#-----------------------------------------------------------------------
# dock widget
#-----------------------------------------------------------------------
dockWidget = QDockWidget("Dock Window", self)
dockWrapper = QWidget()
dockWidget.setWidget(dockWrapper)
dockWidget.setAllowedAreas(Qt.RightDockWidgetArea | Qt.BottomDockWidgetArea)
dockLayout = QVBoxLayout()
dockWrapper.setLayout(dockLayout)
dockDescription = QLabel("This is dock widget contents.")
dockLayout.addWidget(dockDescription)
dockButton = QPushButton("OK")
dockLayout.addWidget(dockButton)
self.addDockWidget(Qt.BottomDockWidgetArea, dockWidget)
def _makeHorizontalLine(self):
hline = QFrame()
hline.setFrameShape(QFrame.HLine)
hline.setFrameShadow(QFrame.Sunken)
return hline
def _makeListWidget(self):
"""
QListWidgetを作成する関数
"""
listWidget = QListWidget()
listWidget.setMaximumWidth(100)
listWidget.addItems(["this", "is", "list", "widget"])
return listWidget
def _makeTableWidget(self):
"""
QTableWidgetを作成する関数
"""
tableWidget = QTableWidget()
headerLabels = ["Name", "Age", "Sex"]
tableWidget.setColumnCount(len(headerLabels))
tableWidget.setHorizontalHeaderLabels(headerLabels)
tableWidget.verticalHeader().setVisible(False)
try:
tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive)
except:
tableWidget.horizontalHeader().setResizeMode(QHeaderView.Interactive)
tableWidget.setAlternatingRowColors(True)
tableWidget.horizontalHeader().setStretchLastSection(True)
dataList = [
["Taro", "25", "Male"],
["Hanako", "30", "Female"],
["Ichiro", "50", "Male"],
["Jiro", "40", "Male"]
]
tableWidget.setRowCount(len(dataList))
for row, colData in enumerate(dataList):
for col, value in enumerate(colData):
item = QTableWidgetItem(value)
tableWidget.setItem(row, col, item)
return tableWidget
def _makeTreeWidget(self):
"""
QTreeWidgetを作成する関数
"""
treeWidget = QTreeWidget()
headerLabels = ["Name", "Age"]
treeWidget.setColumnCount(len(headerLabels))
treeWidget.setHeaderLabels(headerLabels)
treeWidget.setAlternatingRowColors(True)
treeData = {
"Male":[
{"name":"Taro", "age":"25"},
{"name":"Ichiro", "age":"50"},
{"name":"Jiro", "age":"40"}
],
"Female":[
{"name":"Hanako", "age":"30"}
]
}
for sex, profiles in treeData.items():
topItem = QTreeWidgetItem([sex])
treeWidget.addTopLevelItem(topItem)
for profile in profiles:
childItem = QTreeWidgetItem(topItem, [profile.get("name"), profile.get("age")])
treeWidget.expandAll()
return treeWidget
def _showColorDialog(self):
"""
QColorDialog表示スロット
"""
colorDialog = QColorDialog(self)
response = colorDialog.exec_()
if response != QDialog.Accepted:
return
chosen = colorDialog.currentColor()
print("Selected color >> (%d, %d, %d)" % (chosen.red(), chosen.green(), chosen.blue()))
def _showProgressDialog(self):
"""
QProgressDialog表示スロット
"""
max = 100
progressDialog = QProgressDialog("Progress...", "Cancel", 0, max, self)
progressDialog.setWindowTitle("Progress Dialog")
for count in range(max+1):
self.qApp.processEvents()
if progressDialog.wasCanceled():
break
progressDialog.setValue(count)
progressDialog.setLabelText("Progress... %d %%" % count)
time.sleep(0.1)
def _showErrorDialog(self):
"""
QErrorMessage表示スロット
"""
self.errorDialog.showMessage("This is error message.")
def _showInputTextDialog(self):
"""
QInputDialog表示スロット(文字列入力型)
"""
response = QInputDialog.getText(self,
"Input Text",
"Input text here.")
print(response)
def _showInputComboDialog(self):
"""
QInputDialog表示スロット(アイテム選択型)
"""
response = QInputDialog.getItem(self,
"Select Item",
"Select item from the combo box.",
["item1", "item2", "item3", "item4"],
editable=False)
print(response)
def _showCustomDialog(self):
"""
MyDialog表示スロット
"""
dialog = MyDialog()
response = dialog.exec_()
if response == QDialog.Accepted:
print(dialog.getInputText())
def start(app):
maya_win = get_maya_pointer()
ui = DF_TalkUI(parent = maya_win)
ui.myInit(app)
ui.show()
return ui
if __name__ == '__main__':
app = QApplication.instance()
if app is None:
app = QApplication([])
ui = start(app)
app.exec_()スキンウェイトを部分的に頂点を選択してコピーしたい。
1 つの頂点からウェイトをコピーする
1 つの頂点を選択し、そのウェイト値を選択したその他の頂点にコピーすることができます。ウェイト値をペーストする頂点は、同じメッシュ上にあっても別のメッシュ上にあっても構いません。
スキン ポイントのウェイト値をコピーしてペーストするには
スキン ウェイト ペイント ツール(Paint Skin Weights Tool)で、選択(Select)またはペイント選択(Paint Select)モードに切り替えます。

ウェイト値をコピーする頂点を選択し、コピー ツール アイコン をクリックします。ウェイト

値をペーストする頂点を選択し、ペースト ツール アイコン をクリックします。コピーしたウェイト値が選択したすべての頂点にペーストされます。
注:
メッシュから別のメッシュにウェイト値をペーストする場合、ソースの頂点に対応するウェイト値のインフルエンスがターゲット メッシュに見つからない場合はエラーが表示されます。
次のホットキーを使用して、頂点から頂点にウェイト値をコピーしてペーストすることもできます。
(Windows) [Alt]+[Ctrl]+[C]、[Alt]+[Ctrl]+[V]
(Mac OS X) [Option]+[Control]+[C]、[Option]+[Control]+[V]
スキンウェイトを部分的に頂点を選択してコピーしたい。がうまくいかない。
// エラー: file: C:/Program Files/Autodesk/Maya2022/scripts/others/artAttrSkinWeightCopy.mel line 22: 選択した項目が多すぎます。ウェイトをコピーする頂点を 1 つだけ選択してください。 //
C:/Program Files/Autodesk/Maya2022/scripts/others/artAttrSkinWeightPaste.mel
1回コピーさせてペーストするのをループさせればできる?
と思って作ったが、いらなくなったコードサンプル 参考にしかならないけど乗せておく。
global proc artAttrSkinWeightCopy_One()
{
global string $gSkinWeightCopyInfluences[];
global float $gSkinWeightCopyWeights[];
string $sel[] = `ls -sl -flatten`;
if(size($sel) < 1) {
error("選択した項目がありません。ウェイトをコピーする頂点を 1 つだけ選択してください。");
return;
}
if(size($sel) > 1) {
error("選択した項目が多すぎます。ウェイトをコピーする頂点を 1 つだけ選択してください。");
return;
}
string $skinCluster = findSkinClusterFromSelectedComponent($sel[0]);
if($skinCluster == "")
return;
$gSkinWeightCopyInfluences = `skinCluster -q -influence $skinCluster`;
$gSkinWeightCopyWeights = `skinPercent -q -v $skinCluster`;
}
global proc artAttrSkinWeightCopy_multiSelect_test()
{
global string $gSkinWeightCopyInfluences[];
global float $gSkinWeightCopyWeights[];
string $sel[] = `ls -sl -flatten`;
if(size($sel) < 1) {
error("選択した項目がありません。ウェイトをコピーする頂点を 1 つ以上だけ選択してください。");
return;
}
if(size($sel) > 1) {
error("選択した項目が多すぎます。ウェイトをコピーする頂点を 1 つだけ選択してください。");
return;
}
string $skinCluster = findSkinClusterFromSelectedComponent($sel[0]);
if($skinCluster == "")
return;
$gSkinWeightCopyInfluences = `skinCluster -q -influence $skinCluster`;
print("$gSkinWeightCopyInfluences--------------\n");
print($gSkinWeightCopyInfluences);
print("\n--------------\n");
$gSkinWeightCopyWeights = `skinPercent -q -v $skinCluster`;
print("$gSkinWeightCopyWeights--------------\n");
$gSkinWeightCopyWeights_Str=floatArrayToString($gSkinWeightCopyWeights, ",");
print("$gSkinWeightCopyWeights_Str= "+$gSkinWeightCopyWeights_Str);
print("\n--------------\n");
}
global proc artAttrSkinWeightCopy_multiSelect2()
{
$OldSelectVtx = `ls -sl`;
print("$OldSelectVtx");
$OldSelectVtx_Str = stringArrayToString($OldSelectVtx, ",");
print("$OldSelectVtx_Str= "+$OldSelectVtx_Str+"\n");
//UIで選択しておく
$BaseMesh = "|Mesh|Arm_Only5";
$PastMesh = "|Mesh|Jacket_For_ShortSkirtUV";
select($BaseMesh);
string $selectBaseVtx[] = `polyInfo -nonManifoldVertices`;
//string $selectBaseVtx[] = `ls -sl -flatten`;
select($PastMesh);
string $selectPastVtx[] = `polyInfo -nonManifoldVertices`;
//string $selectPastVtx[] = `ls -sl -flatten`;
//選択した頂点を再選択
select($OldSelectVtx);
$selectBaseVtx_len = `size($selectBaseVtx)`;
$selectBaseVtx_Str = stringArrayToString($selectBaseVtx, ",");
print("$selectBaseVtx_Str= "+$selectBaseVtx_Str+"\n");
print("$selectBaseVtx_len= "+$selectBaseVtx_len+"\n");
for($i = 0; $i < $selectBaseVtx_len; $i++)
{
select($selectBaseVtx[$i]);
print("$selectBaseVtx["+$i+"] \n");
//artAttrSkinWeightCopy;
select($selectPastVtx[$i]);
print("$selectPastVtx["+$i+"] \n");
//artAttrSkinWeightPaste;
}
select($OldSelectVtx);
}
artAttrSkinWeightCopy_multiSelect2();参考URL
https://help.autodesk.com/view/MAYACRE/JPN/?guid=GUID-7D895BB0-1522-4388-96E0-4245127F90AB
お客様のチャット
<!-- chat.php -->
<?php
function trace($txt){
//print($txt);
$a="a";
}
class RoomLog
{
public $LOG_FILE_NAME;
public $name;
public $SPLIT_Str;
public $message;
public function get_ip_file_name(){
global $_SERVER;
$ip_Address=$_SERVER['REMOTE_ADDR'];
print("ip_Address= " . $ip_Address . "<br>");
if($ip_Address=="::1"){
$ip_Address="192.168.1.29";
print("テストのためip変数上書きしました。ip_Address= " . $ip_Address . "<br>");
}
$ip_Address_Arr = explode(".", $ip_Address);
$ip_file_name = join('_', $ip_Address_Arr);
$ip_file_name = "log/ip_" . $ip_file_name . "_chatlog.txt";
print("ip_file_name= " . $ip_file_name . "<br>");
return $ip_file_name;
}
public function initLog(){
trace("■ initLog()<br>");
global $LOG_FILE_NAME;
global $name;
global $SPLIT_Str;
global $message;
$ip_file_name=$this->get_ip_file_name();
// データを書き込むファイルの名前
//$LOG_FILE_NAME = "chat_class_txt_log.txt";
$LOG_FILE_NAME = $ip_file_name;
// 区切りのための文字列
$SPLIT_Str = "|-|";
// 名前を格納する変数
$name = "お客様";
// メッセージを格納する変数
$message = "";
$this->LOG_FILE_NAME=$LOG_FILE_NAME;
$this->name=$name;
$this->SPLIT_Str=$SPLIT_Str;
$this->message=$message;
/*
trace("<br>");
trace("this->LOG_FILE_NAME= " . $this->LOG_FILE_NAME . "<br>");
trace("this->name= " . $this->name . "<br>");
trace("this->SPLIT_Str= " . $this->SPLIT_Str . "<br>");
trace("this->message= " . $this->message . "<br>");
*/
}
public function startMain(){
trace("■ startMain()<br>");
$this->initLog();
$this->CheckFormPostData();
$this->LogShow();
}
public function CheckFormPostData(){
trace("■ CheckFormPostData()<br>");
global $_POST;
$name = $this->name;
$SPLIT_Str = $this->SPLIT_Str;
$message = $this->message;
// 送信されたデータ
$_POST_string = join(', ', $_POST);
trace("_POST_string2= " . $_POST_string . "<br>");
if (empty($_POST)) {
trace("The form is empty.");
} else {
trace("Form data is present.");
}
// 送信された名前とメッセージを変数に代入
if (isset($_POST['name'])) {
$name = $_POST['name'];
if (strpos($name, $SPLIT_Str) !== false) {
// 名前に区切り文字が含まれている場合の処理
echo "使用できない文字列「|-|」が含まれています。";
return;
}
if ($name == "") {
$name = "お客様";
}
}
if (isset($_POST['message'])) {
$message = $_POST['message'];
if (strpos($message, $SPLIT_Str) !== false) {
// メッセージに区切り文字が含まれている場合の処理
echo "使用できない文字列「|-|」が含まれています。";
return;
}
//$this->LOG_FILE_NAME=$LOG_FILE_NAME;
$this->name=$name;
//$this->SPLIT_Str=$SPLIT_Str;
$this->message=$message;
$this->LogWrite();
}
}
public function LogWrite(){
trace("■ LogWrite()<br>");
$LOG_FILE_NAME = $this->LOG_FILE_NAME;
$name = $this->name;
$SPLIT_Str = $this->SPLIT_Str;
$message = $this->message;
//書き込みモードでファイルを開く
$fp = fopen($LOG_FILE_NAME, "a") or exit($LOG_FILE_NAME . "が開けません");
// | を区切り文字として2つのデータを繋げて書き込む
fwrite($fp, $name . $SPLIT_Str . $message . "\n");
// リダイレクトのためのHTTPヘッダーを送信
//header("Location: " . $_SERVER['PHP_SELF'], true, 303);
fclose($fp);
}
function LogShow(){
trace("■ LogShow()<br>");
//global $LOG_FILE_NAME;
global $linesNum;
global $lines;
$LOG_FILE_NAME = $this->LOG_FILE_NAME;
//$name = $this->name;
//$SPLIT_Str = $this->SPLIT_Str;
//$message = $this->message;
if (!file_exists($LOG_FILE_NAME)) {
// ファイルがない場合
echo "書き込みはありません。";
$linesNum = 0;
} else {
// ファイルの全行を読み取る
$lines = file($LOG_FILE_NAME);
// 読み込んだ行数
$linesNum = count($lines);
}
}
}
$RoomLog_ins = new RoomLog();
$RoomLog_ins->startMain();
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>1行メッセージ</title>
</head>
<body>
<h1>お問い合わせ内容</h1>
<section>
<?php
// 一行ずつ表示する処理
for ($i = 0; $i < $linesNum; $i++) {
// 区切り文字でデータを区切って配列に格納
$array = explode($SPLIT_Str, $lines[$i]);
// 区切り文字の前の部分は名前
$name = htmlspecialchars($array[0]);
// 区切り文字の後の部分はメッセージ
$array_length = count($array);
if ($array_length == 2) {
$message = htmlspecialchars($array[1]);
}
// 名前とメッセージを表示
echo '<p>' . $name . "「" . str_replace(PHP_EOL, "", $message) . '」</p>';
}
?>
</section>
<form method="post" action="chat_class_txt.php">
<div>
<!--<b>おなまえ</b>-->
<!--<input name="name" type="text" size="20" maxlength="10">-->
<input name="name" type="hidden" size="20" maxlength="10">
</div>
<div>
<!--<b>ご入力</b>-->
<input name="message" type="text" size="50" maxlength="50" required>
<button name="submit" type="submit">送信</button>
</div>
</form>
</body>
</html>担当者のチャット画面
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>1行メッセージ</title>
</head>
<body>
<!-- chat.php -->
<style>
.base {
display: flex;
flex-direction: row;
width: 100vw;
height: 90vh;
}
.class1 {
width: 10%;
}
.class2 {
display: flex;
flex-direction: column;
width: 90%;
}
</style>
<style>
div {
text-align: center;
/* background-color: #aaaaaa; 16進数のカラーコードを使用する例 */
}
button{
font-size: 200%;
width:100px;
height:100px;
}
</style>
<div class="base">
<div class="class1">
<?php
//$dir = "log";
//$files = scandir($dir);
$files = glob("log/*");
$counter=0;
foreach ($files as $file) {
//echo("<h2>" . $file . "</h2><br>");
$url='log_frame.php';
//echo('<a href="'.$url.'"><h1><div >' . $counter . '</div></h1></a><br>');
$htmlStr='';
$htmlStr=$htmlStr.'<form method="post" action="chat_class_txt_admin.php">';
$htmlStr=$htmlStr.'<input type="hidden" name="LOG_FILE_NAME" value="' . $file . '">';
$htmlStr=$htmlStr.'<button name="submit" type="submit">' . $counter . '</button>';
$htmlStr=$htmlStr.'</form>';
echo($htmlStr);
$counter=$counter+1;
}
?>
</div>
<div class="class2">
<?php
function trace($txt){
//print($txt);
$a="a";
}
class RoomLog
{
public $LOG_FILE_NAME;
public $LOG_FILE_NAME_Opened;
public $name;
public $SPLIT_Str;
public $message;
public function get_ip_file_name(){
global $_SERVER;
$ip_Address=$_SERVER['REMOTE_ADDR'];
trace("ip_Address= " . $ip_Address . "<br>");
if($ip_Address=="::1"){
$ip_Address="192.168.1.29";
trace("テストのためip変数上書きしました。ip_Address= " . $ip_Address . "<br>");
}
$ip_Address_Arr = explode(".", $ip_Address);
$ip_file_name = join('_', $ip_Address_Arr);
$ip_file_name = "log/ip_" . $ip_file_name . "_chatlog.txt";
trace("ip_file_name= " . $ip_file_name . "<br>");
return $ip_file_name;
}
public function CheckFormPostData_Admin(){
trace("■ CheckFormPostData_Admin()<br>");
global $_POST;
// 送信されたデータ
$_POST_string = join(', ', $_POST);
trace("_POST_string1= " . $_POST_string . "<br>");
if (empty($_POST)) {
trace("The form is empty.<br>");
} else {
trace("Form data is OK present.<br>");
}
if (isset($_POST['LOG_FILE_NAME'])) {
$LOG_FILE_NAME = $_POST['LOG_FILE_NAME'];
$this->LOG_FILE_NAME=$LOG_FILE_NAME;
print("LOG_FILE_NAME= " . $LOG_FILE_NAME . "<br>");
}
/*
// 送信された名前とメッセージを変数に代入
if (isset($_POST['name'])) {
$name = $_POST['name'];
if (strpos($name, $SPLIT_Str) !== false) {
// 名前に区切り文字が含まれている場合の処理
echo "使用できない文字列「|-|」が含まれています。";
return;
}
if ($name == "") {
$name = "お客様";
}
}
if (isset($_POST['message'])) {
$message = $_POST['message'];
if (strpos($message, $SPLIT_Str) !== false) {
// メッセージに区切り文字が含まれている場合の処理
echo "使用できない文字列「|-|」が含まれています。";
return;
}
//$this->LOG_FILE_NAME=$LOG_FILE_NAME;
$this->name=$name;
//$this->SPLIT_Str=$SPLIT_Str;
$this->message=$message;
$this->LogWrite();
}
*/
return $LOG_FILE_NAME;
}
public function initLog(){
trace("■ initLog()<br>");
global $LOG_FILE_NAME;
global $name;
global $SPLIT_Str;
global $message;
$ip_file_name=$this->CheckFormPostData_Admin();
// データを書き込むファイルの名前
//$LOG_FILE_NAME = "chat_class_txt_log.txt";
$LOG_FILE_NAME = $ip_file_name;
// 区切りのための文字列
$SPLIT_Str = "|-|";
// 名前を格納する変数
$name = "担当者";
// メッセージを格納する変数
$message = "";
$this->LOG_FILE_NAME=$LOG_FILE_NAME;
$this->name=$name;
$this->SPLIT_Str=$SPLIT_Str;
$this->message=$message;
/*
trace("<br>");
trace("this->LOG_FILE_NAME= " . $this->LOG_FILE_NAME . "<br>");
trace("this->name= " . $this->name . "<br>");
trace("this->SPLIT_Str= " . $this->SPLIT_Str . "<br>");
trace("this->message= " . $this->message . "<br>");
*/
}
public function startMain(){
trace("■ startMain()<br>");
$this->initLog();
$this->CheckFormPostData();
$this->LogShow();
}
public function CheckFormPostData(){
trace("■ CheckFormPostData()<br>");
global $_POST;
$name = $this->name;
$SPLIT_Str = $this->SPLIT_Str;
$message = $this->message;
// 送信されたデータ
$_POST_string = join(', ', $_POST);
//trace("_POST_string2= " . $_POST_string . "<br>");
if (empty($_POST)) {
trace("The form is empty.<br>");
} else {
trace("Form data is present.<br>");
}
// 送信された名前とメッセージを変数に代入
if (isset($_POST['name'])) {
$name = $_POST['name'];
if (strpos($name, $SPLIT_Str) !== false) {
// 名前に区切り文字が含まれている場合の処理
echo "使用できない文字列「|-|」が含まれています。<br>";
return;
}
if ($name == "") {
$name = "担当者";
}
}
if (isset($_POST['message'])) {
$message = $_POST['message'];
if (strpos($message, $SPLIT_Str) !== false) {
// メッセージに区切り文字が含まれている場合の処理
echo "使用できない文字列「|-|」が含まれています。<br>";
return;
}
//$this->LOG_FILE_NAME=$LOG_FILE_NAME;
$this->name=$name;
//$this->SPLIT_Str=$SPLIT_Str;
$this->message=$message;
$this->LogWrite();
}
}
public function LogWrite(){
trace("■ LogWrite()<br>");
$LOG_FILE_NAME = $this->LOG_FILE_NAME;
$name = $this->name;
$SPLIT_Str = $this->SPLIT_Str;
$message = $this->message;
//書き込みモードでファイルを開く
$fp = fopen($LOG_FILE_NAME, "a") or exit($LOG_FILE_NAME . "が開けません<br>");
// | を区切り文字として2つのデータを繋げて書き込む
fwrite($fp, $name . $SPLIT_Str . $message . "\n");
// リダイレクトのためのHTTPヘッダーを送信
//header("Location: " . $_SERVER['PHP_SELF'], true, 303);
fclose($fp);
}
function LogShow(){
trace("■ LogShow()<br>");
//global $LOG_FILE_NAME;
global $linesNum;
global $lines;
$LOG_FILE_NAME = $this->LOG_FILE_NAME;
//$name = $this->name;
//$SPLIT_Str = $this->SPLIT_Str;
//$message = $this->message;
if (!file_exists($LOG_FILE_NAME)) {
// ファイルがない場合
echo "書き込みはありません。<br>";
$linesNum = 0;
} else {
// ファイルの全行を読み取る
$lines = file($LOG_FILE_NAME);
// 読み込んだ行数
$linesNum = count($lines);
}
}
}
$RoomLog_ins = new RoomLog();
$RoomLog_ins->startMain();
?>
<h1>お問い合わせ内容</h1>
<section>
<?php
// 一行ずつ表示する処理
for ($i = 0; $i < $linesNum; $i++) {
// 区切り文字でデータを区切って配列に格納
$array = explode($SPLIT_Str, $lines[$i]);
// 区切り文字の前の部分は名前
$name = htmlspecialchars($array[0]);
// 区切り文字の後の部分はメッセージ
$array_length = count($array);
if ($array_length == 2) {
$message = htmlspecialchars($array[1]);
}
// 名前とメッセージを表示
echo '<p>' . $name . "「" . str_replace(PHP_EOL, "", $message) . '」</p>';
}
?>
</section>
<form method="post" action="chat_class_txt_admin.php">
<div>
<!--<b>おなまえ</b>-->
<!--<input name="name" type="text" size="20" maxlength="10">-->
<input name="name" type="hidden" size="20" maxlength="10">
</div>
<div>
<!--<b>ご入力</b>-->
<?php
echo('<input type="hidden" name="LOG_FILE_NAME" value="' . $LOG_FILE_NAME . '">');
?>
<input name="message" type="text" size="50" maxlength="50" required>
<button name="submit" type="submit">送信</button>
</div>
</form>
</div><!--div class="class2"-->
</div><!--div class="base"-->
</body>
</html>こちらのサイトを参考にしました。
PHPで作るチャット(7) クロスサイトスクリプティング(XSS)の修正
このPHPをクラスベースで書き直しました。